第 12 章 語言擴展
22 廣義 open 語句
(於 4.08 版本引入)
此擴展使得在模組結構和表達式中可以開啟任何模組表達式。類似的機制也適用於模組類型內部,但僅限於擴展模組路徑 (例如 F(X).G(Y))。
例如,一個模組可以在開啟時使用以下方式約束:
module M = struct let x = 0 let hidden = 1 end open (M:sig val x: int end) let y = hidden
錯誤:未綁定值 hidden
另一種可能性是立即開啟函子應用程序的結果
let sort (type x) (x:x list) = let open Set.Make(struct type t = x let compare=compare end) in elements (of_list x)
val sort : 'x list -> 'x list = <fun>
更進一步,此結構可以在結構體內部引入局部組件,
module M = struct let x = 0 open! struct let x = 0 let y = 1 end let w = x + y end
module M : sig val x : int val w : int end
一個重要的限制是,由 open struct ... end 引入的類型不能出現在封閉結構的簽名中,除非它們被定義為等於某個非局部類型。所以
module M = struct open struct type 'a t = 'a option = None | Some of 'a end let x : int t = Some 1 end
module M : sig val x : int option end
這樣可以,但是
module M = struct open struct type t = A end let x = A end
錯誤:此 open 引入的類型 t 出現在簽名中。如果 t 被隱藏,則值 x 沒有有效的類型。
不行,因為 x 無法被賦予除了 t 之外的任何類型,而 t 僅在局部存在。儘管如果 x 也是局部的,則以上程式碼會沒問題
module M: sig end = struct open struct type t = A end … open struct let x = A end … end
module M : sig end
在簽名內,擴展的 open 僅限於擴展模組路徑,
module type S = sig module F: sig end -> sig type t end module X: sig end open F(X) val f: t end
module type S = sig module F : sig end -> sig type t end module X : sig end val f : F(X).t end
而不是
open struct type t = int end
在這些情況下,可以使用局部替換(參見12.7.2)。
請注意,此擴展在類別定義中不可用
class c =
let open Set.Make(Int) in
...
Copyright © 2024 Institut National de Recherche en Informatique et en Automatique