为什么我不能在OCaml中强制记录类型?像int
这样的基类型可以正常工作。
下面是我构建模块M
中包含的基础模块A
的示例。 M.t
中的A
类型属于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
在顶层:
{{1}}
答案 0 :(得分:3)
那是因为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
保留了相等性(否则它与签名不匹配{ {1}}),与type t' = private M.t
代替M
的内容不同。但这显然不适用于创造新类型的include M
..