我最终试图做的事情是1)限制对模块(因此mli文件)的可见性和2)定义一个函子,其中参数具有“规范实现“,它作为一个ml
/mli
对生活在源码树中,并坚持参数具有与此规范实现相同的形状。mml文件和ml文件里签名之间的OCaml共享结构
假设我有一个包含字符串连接
(* concat.ml *)
type t = string
let concat x y = x^y
单一功能的文件concat.ml
和我有一个接口,它
(* concat.mli *)
type t
val concat : t -> t -> t
不过,我也有一个仿函数join
,看起来像这并且期望与Concat
具有相同形状的东西。 (中join
实施是故意天真):
(* join.ml *)
module Join(X : Concat_type.TYPE) : sig
val join : X.t list -> X.t
end = struct
let rec join xs = match xs with
| [] -> failwith "can't be empty"
| [x] -> x
| [x; y] -> X.concat x y
| (x::xs') -> X.concat x (join xs')
end
为了表达“相同形状的毗连”的约束,我只好再拍ml
文件concat_type.ml
看起来像这样:
(* concat_type.ml *)
module type TYPE = sig
type t
val concat : t -> t -> t
end
Concat_type.TYPE
和Concat
mli在这种情况下几乎相同。我所做的concat_type.ml
的唯一原因是为了支持函子Join
,并明确限制它可以看到的内容,如果我尝试将其应用于模块执行concat
的模块。
有没有办法将Concat_type.TYPE
导入到Concat
界面,反之亦然,或者有其他方式避免它们之间的重复?
你应该能够只使用'包括Concat_type.TYPE'在concat.mli,我觉得 – glennsl
你可以用'Concat'的模块类型,例如,'模块加入(X:Concat的模块类型):sig ...'。 – gsg