mam文件和ml文件中的签名之间的OCaml共享结构

时间:2017-10-17 20:59:17

标签: types module ocaml

我最终要做的事情是1)限制对模块的可见性(因此mli文件)和2)定义一个仿函数,其中参数具有"规范实现"它作为ml / mli对存在于源树中,并坚持认为参数具有与此规范实现相同的形状。

假设我有一个文件concat.ml,其中包含一个字符串连接函数

(* concat.ml *)
type t = string
let concat x y = x ^ y

我有一个界面

(* 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.TYPEConcat mli几乎相同。我提出concat_type.ml的唯一原因是支持仿函数Join,并明确限制它可以看到的内容,如果我尝试将其应用于模仿concat实现的模块。

有没有办法将Concat_type.TYPE导入Concat界面,反之亦然或以其他方式导入,以避免它们之间的重复?

1 个答案:

答案 0 :(得分:1)

是的,可以通过Concat模块类型表达Concat_type.TYPE模块接口。也可以获得现有模块的模块类型。

第一种方法如下:

(* concat.mli *)
include Concat_type.TYPE

第二种方法允许你摆脱Concat_type,虽然我个人不喜欢它,因为我不喜欢module type of构造。但仍有可能:

module type Concat = module type of Concat

module Join (X : Concat) = struct 
  ...
end