我不知道这个问题到底在说什么,但关于你的代码片段,有各种非常不同的方式来解释你正在尝试做的事情。
您目前正在做的是密封A
并B
在两个抽象的、不兼容的签名下,然后尝试将它们混合在一个模块中,只是为了产生名称冲突。
也许您只是想避免名称冲突。当然,最简单的解决方案是不要对类型A.t
和B.t
. 然后你可以“不包括B
”:
module C = struct
include A
let x_b = B.x
end
更好的解决方案是使用 OCaml 3.12 破坏性替换签名,with type t := foo
来屏蔽t
模块中的类型B
:
module C = struct
include A
type u = B.t (* rename B.t into 'u' to avoid name conflict *)
include (B : XSig with type t := u) (* replaces 't' by 'u' *)
end
您可能还希望模块的类型A
兼容B
。在这种情况下,您不能用抽象类型密封它们。
module type XSig = sig
type t
val x : t
end
module A = struct
type t = int
let x = 0
end
(* if you want to check that A can be sealed by XSig, do it here,
outside the main declaration *)
let _ = (module A : XSig)
module B = struct
type t = int
let x = 1
end
module C = struct
include (A : XSig with type t := int)
include (B : XSig with type t := int)
end
(* module C : sig
val x = int
end *)
在这个例子中,两种类型A.t
和B.t
都被破坏性替代删除:=
。如果您希望您的模块C
有一个 type t
,您可以编写以下任一项:
module C = struct
type t = int
include (A : XSig with type t := t)
include (B : XSig with type t := t)
end
或者,使用非破坏性替换(更改类型定义而不是删除它):
module C = struct
include (A : XSig with type t = int)
include (B : XSig with type t := t)
end
有关更多详细信息,请参见破坏性替换的手册页,以及用于比较type type t := ...
的经典with type t = ...
构造的手册页。