Ocaml 强制类型缩写记录
为什么我不能强制OCaml中的记录类型?像Ocaml 强制类型缩写记录,ocaml,record,coercion,Ocaml,Record,Coercion,为什么我不能强制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
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
这是因为
A.t'
与M.t
没有关系,因为include
没有“保留”相等性,它只是字面上复制模块结构(或签名)并将其内联(作为新的类型和值)。因此类型M.t
与A.t
没有任何关系,因此与A.t'
没有任何关系(不同的记录类型没有定义结构子类型,比如说对象或模块)。
明显的修正是类型t'=private M.t
更新
上面的说法似乎不完全正确,因为签名中的
type t'=private M.t
,以及实现中的include M type t'=t
,所以include M
保留了平等性(否则它无法匹配签名type t'=private M.t
),与复制粘贴不同,将M
的内容替换为include M
。但这“显然”不适用于创建新类型的包含模块类型的。另一个修复方法是明确声明,当包含模块类型时,您希望类型相等:包含类型为t=M.t的M模块类型。您知道为什么这对于记录类型是必需的,而对于基本类型(如int
)则不是必需的吗?如果将t更改为type t=int
,则上述代码将起作用。因为在type t=int
和type t'=int
中,t
和t'
是现有类型的别名(类型缩写),可以互换使用。但是typet={x:int}
和typet'={x:int}
——这是两种新类型,根本不相关。