OCaml手册第二章说
是一个结构体,由struct…end构造引入,该构造体包含一个任意的定义序列。该结构通常与模块绑定一起给定一个名称。
是否有创建一个结构体而不给它一个模块名的用例?如果不是,那么我们总是使用
module Name =
struct
...
end
,因此struct关键字似乎有点多余。
使用无名结构是可能的,甚至是常见的(至少在我的代码中)。一个例子:
module MyStrSet =
Set.Make(struct type t = string let compare a b = compare b a end)
稍微扩展一下Jeffrey的回答,OCaml函子将一个模块映射到另一个模块。它不关心模块的名称。
考虑下面这个简单的例子:
module type SIG =
sig
val x : int
end
module A (B : SIG) =
struct
let y = B.x * 2
end
我定义了一个函子A
,它取一个模块B
,满足模块类型SIG
。现在,我可以定义一个模块Twenty_one
,它提供21
的x
值,然后把它给函子A
来创建模块C
。
module Twenty_one =
struct
let x = 21
end
module C = A (Twenty_one)
或者我可以直接使用匿名结构
module C = A (struct let x = 21 end)
我们甚至不需要来命名SIG
。
module A (B : sig val x : int end) =
struct
let y = B.x * 2
end
module C = A (struct let x = 21 end)
强烈进入意见领域,但如果有助于重用和表达性,您可能希望在代码中为命名。
。
module Int =
struct
type t = int
let compare = compare
end
module Int_map = Map.Make (Int)
与
module Int_map = Map.Make (struct type t = int let compare = compare end)
使用匿名结构可以做的另一件事,与最近(从4.08.0开始)的OCaml更相关,是使用open
的能力,以一种语法上便宜的方式隐藏名称空间中的名称(直到您编写接口文件):
open struct
type hidden_type = string
let hidden_name = 42
end
此功能称为泛化打开,相关手册页在这里。