强制类型缩写记录



为什么我不能在OCaml中强制记录类型?像int这样的基本类型运行良好。

下面是一个例子,我构造了一个基本模块M,我将其包括在模块A中。CCD_ 4是CCD_。只要M.tint,我就可以做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.tA.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。。

最新更新