第 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 也在本地,上面的代码会是 OK 的
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
...
版权所有 © 2024 法国国家信息与自动化研究院