OCaml 允许在签名中将类型标记为私有。这是有道理的。声明为 private 类型的对象只能在模块内部创建并在外部读取。
module X : sig
type t = private { value : int }
val make : int -> t
end = struct
type t = { value : int }
let make x = { value = x }
end
let x = X.make 3 (* OK *)
let value = x.value (* OK *)
let x = X.{ value = 3 } (* ERROR *)
很清楚。但 OCaml 还提供了在模块结构内声明私有类型的能力。
module X : sig
type t = private { value : int }
val make : int -> t
end = struct
type t = private { value : int }
let make x = { value = x } (* ERROR *)
end
错误:无法创建私有类型 t 的值
它看起来像一个愚蠢的功能,因为当不可能创建类型的任何对象时,没有人需要它。
对我来说,当 private 是仅在签名级别(如抽象类型)中允许的属性时,看起来更合乎逻辑。
OCaml 结构体中的私有类型有何用途?
出于同样的原因,您可以声明完全抽象类型:例如,这些类型的值可以由外部函数创建
type t = private int
external f: unit -> t = "some_c_function"
此外,这使得类型定义更加规则,因为签名和结构中始终允许相同的类型定义。