我注意到Janestreet的Core库使用了以下几种模式:
module Intf = struct
type 'a t = Value of 'a
module type T = sig
type nonrec 'a t = 'a t
val some_function : unit -> int t
end
end
module M : Intf.T = struct
include Intf
let some_function () = Value 42
end
我发现它很好,因为它允许我在一个地方维护我的类型(通常在_intf.ml文件中)。
我的问题是它使M.t不透明,所以我不能直接执行以下操作:
let _ = M.Value 42
Error: Unbound constructor M.Value
有没有办法解决这种问题?
编辑:
这是一个看起来更像我真实的例子:
在m_intf.ml中:
module Intf = struct
type 'a t = Value of 'a
module type M = sig
type nonrec 'a t = 'a t
end
end
在m.ml中:
include Intf
let some_public_function () = Value 42
let some_hidden_function () = (* ... *)
在m.mli:
include M_intf.M
val some_public_function : unit -> int t
答案 0 :(得分:1)
您已使用'a t
明确隐藏了Intf.T
类型的定义。
module M = struct
include Intf
let some_function () = Value 42
end
如果你删除它,你会看到它回来了。
此外,当您为变体类型创建类型缩写时,它并不自动意味着您将构造函数带入范围。例如,
module Maybe = struct
type 'a t = Nothing | Just of 'a
end
type 'a t = 'a Maybe.t
然后,您仍然需要使用模块名称限定构造函数,例如Maybe.Nothing
。
如果您真的想将它们带入模块范围,那么您需要:
type 'a t = 'a Maybe.t = Nothing | Just of 'a