如何合并定义相同类型的OCaml模块类型(签名)?

如何合并定义相同类型的OCaml模块类型(签名)?,ocaml,Ocaml,在OCaml中,我有两种模块类型定义类型t: module type Asig = sig type t val a : t end module type Bsig = sig type t val b : t end 我想自动创建一个模块类型来合并它们。我想创建一个模块类型,相当于: module type ABsig_manual = sig type t val a : t val b : t end 我试过了 module

在OCaml中,我有两种模块类型定义类型
t

module type Asig = sig
    type t
    val a : t
end

module type Bsig = sig
    type t
    val b : t
end
我想自动创建一个模块类型来合并它们。我想创建一个模块类型,相当于:

module type ABsig_manual = sig
    type t
    val a : t
    val b : t
end
我试过了

module type ABsig = sig
    include Asig
    include Bsig
end
但此操作失败,出现
错误:类型名t的多个定义
。似乎不可能将类型约束添加到
include
中,所以我被卡住了

上下文:我有一个模块
AB
,它实现了两个签名,我想把它提供给一个函子,比如:

module MakeC(AB) = struct
    type t = AB.t list
    let c = [AB.a; AB.b]
end

module C = MakeC(AB)
我可以使用两个参数,如:

module UglyMakeC(A : Asig)(B : Bsig with type t = A.t) = struct
    type t = A.t list
    let c = [A.a; B.b]
end

module C = UglyMakeC(AB)(AB)
但这(很难看,而且)不能很好地扩展到更多的函子或更多要合并的签名

那么,如何自动合并这两种模块类型呢?我可以根据需要修改A和B,但我希望将它们分开。而且,也许我的方法完全错了,在这种情况下,我希望能找到更好的方向


是相关的,但合并模块,而不是模块类型。

以下是实现此目的的方法:

module type Asig = sig
    type t
    val a : t
end

module type Bsig = sig
    type t
    val b : t
end

module type ABsig = sig
    include Asig
    include Bsig with type t := t
end

这就是所谓的“破坏性替代”。

你有没有考虑过<代码> CAML?list@inria.fr
?为了便于将来参考,这一点在“语言扩展”中的“在签名内替换”一段()中进行了说明,它扩展了“OCaml语言”一段“模块类型”(Module types)中所述内容。更持久的参考链接:(参考手册中的secXXX锚固件针对每个新版本的OCaml进行了修改)现实世界的OCaml(第186-187页)提出了一种针对这种情况的替代解决方案,解释说“当组合多个接口时,这稍微干净一些,因为它正确地反映了所有签名都被同等地处理。”:
模块类型ABsig=sig类型t包含Asig类型t:=t包含Bsig类型t:=t结束