因此,当您定义模块的结构时,可以将另一个模块扩展为:
module Base = struct
type t = Name of string
end
module Child = struct
include Base
end
Child.Name "test"
(* - : Child.t = Child.Name "test" *)
但是,当使用递归签名使用递归模块时,当我尝试扩展一个模块时,我会遇到问题:
module rec Base : sig
type t = | Name of string
end = Base
and Child : sig
include Base
end = Child
当我这样做时,我会发现一个错误:
Error: Unbound module type Base
使用此递归模块技巧时,您不能扩展模块吗?我是在误解某件事还是做错了什么?
在我看来,您的问题是Base
是一个模块,而不是模块类型。在sig ... end
构造中包括时,您需要类型。在struct ... end
构造中包括一个模块时。这就是为什么第一个示例工作,第二个示例不起作用。
如果我将Base
更改为module type of Base
,我会得到此错误:
Error: Illegal recursive module reference
所以我怀疑不支持这种特殊的递归定义(有些奇怪(。
如果单独定义模块类型,则可以使其起作用:
module type BASE = sig type t = Name of string end
module rec Base : BASE = Base
and Child : sig
include BASE
end = Child
杰弗里·斯科菲尔德(Jeffrey Scofield(已经给出了一个很好的答案。我只想补充一点,include
只是句法糖。因此,如果是include
,这会导致您麻烦,则可能是将其扩展。在您的第一个示例中,会导致
module Base = struct
type t = Name of string
end
module Child = struct
type t = Name of string
end
显然,您的示例是您真正想做的事情的简化版本。如图所示,根本不需要使用rec
。因此,我只能猜测您真正需要多少递归。根据Jeffrey Scofield的回答,rec
和include
的组合是有问题的。可能,摆脱include
足以满足您的需求。