我最终要做的是 1) 限制对模块的可见性(因此是 mli 文件)和 2) 定义一个仿函数,其中参数具有作为 ml
/mli
对并坚持认为参数与此规范实现具有相同的形状。
假设我有一个文件concat.ml
,其中包含一个用于字符串连接的函数
(* concat.ml *)
type t = string
let concat x y = x ^ y
我有一个接口(interface)
(* 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
为了表达“与 Concat 相同的形状”约束,我不得不制作另一个 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_type.TYPE
导入到 Concat
接口(interface)中,反之亦然,或者有其他方法可以避免它们之间的重复?
最佳答案
是的,可以通过Concat_type.TYPE
模块类型来表达Concat
模块接口(interface)。也可以获取现有模块的模块类型。
第一种方法是这样的:
(* concat.mli *)
include Concat_type.TYPE
第二种方法允许您摆脱 Concat_type
,但我个人不喜欢它,因为我不喜欢 module type of
构造。但是,仍然有可能:
module type Concat = module type of Concat
module Join (X : Concat) = struct
...
end
关于types - mli 文件和 ml 文件中的签名之间的 OCaml 共享结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46799140/