为什么我不能在OCaml中强制记录类型?像int
这样的基本类型运行良好。
下面是一个例子,我构造了一个基本模块M
,我将其包括在模块A
中。CCD_ 4是CCD_。只要M.t
是int
,我就可以做A.t' :> M.t
。当我将其更改为{i : int}
时,编译器会说它不是一个子类型。我猜这其中有一个非常具体的原因?
module M = struct
type t = {i : int}
let make () = {i = 10}
end
module A : sig
include module type of M
type t' = private t
val make : unit -> t'
end = struct
include M
type t' = t
end
在顶层:
(A.make() :> M.t);;
Error: Type A.t' is not a subtype of M.t
这是因为A.t'
与M.t
没有关系,因为include
不"保持"相等性,它只是从字面上复制模块结构(或签名)并将其内联(作为新的类型和值)。因此类型M.t
与A.t
没有任何关系,因此与A.t'
也没有任何关系(并且不同的记录类型没有像对象或模块那样定义结构子类型)。明显的修复是type t' = private M.t
。
更新
上面的内容似乎并不完全正确,因为签名中的type t' = private M.t
和实现中的include M type t' = t
进行类型检查,所以include M
保持相等(否则它无法与签名type t' = private M.t
匹配),而不是将M
的内容复制粘贴到include M
的位置。但这"显然"不适用于创建新类型的include module type of
。。