OCaml:如何获取mli文件的本地模块别名

时间:2017-09-26 02:06:29

标签: ocaml

是否可以在mli中为模块添加别名而无需创建“必须实现的新模块”。 这个例子非常有用,但是,例如,假设我有以下源文件int_wrapper.ml。

type t = Int64.t

let zero = Int64.of_string "0"

我想为它定义一个接口文件,但Int64.t很长,所以我想缩写它。

module I = Int64

val zero : int -> I.t

尝试编译模块时,我(可预见地)会收到以下错误

ocamlbuild int_wrapper.cmo
+ ~/.opam/4.03.0/bin/ocamlc.opt -c -o int_wrapper.cmo int_wrapper.ml
File "int_wrapper.ml", line 1:
Error: The implementation int_wrapper.ml
   does not match the interface int_wrapper.cmi:
   The module `I' is required but not provided
Command exited with code 2.
Compilation unsuccessful after building 4 targets (0 cached) in 00:00:00.
Exit 10

那是因为module I = Int64不是别名。我实际上是在定义一个与Int64恰好相同的新模块,因为该模块是签名的,所以我需要在源文件中提供一个实现。 有没有办法在接口文件中获得真正的别名?

3 个答案:

答案 0 :(得分:3)

模块别名需要出现在.ml.mli文件中,因为它们正在导出。您可以将它们放在使用open的单独文件中解决,例如:

==> abbrevs.ml <==
module I = Int64

==> int_wrapper.ml <==
type t = Int64.t

let zero = Int64.of_string "0"

==> int_wrapper.mli <==
open Abbrevs
val zero : I.t

答案 1 :(得分:2)

无法在.mli文件中包含本地使用的模块同义词(据我所知,通过查看OCaml语法定义)。

如果您愿意在.ml文件和.mli文件中定义I,则.ml文件将提供正确的接口。

$ cat a.ml
module I = Int64
type t = I.t
let zero = I.of_string "0"
$ cat a.mli
module I = Int64
type t = I.t
val zero : I.t
$ ocamlc -c a.mli a.ml

答案 2 :(得分:2)

从OCaml 4.08开始(请参见release notes),现在可以通过local substitution declarations来实现:

module I := Int64