是否可以在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
恰好相同的新模块,因为该模块是签名的,所以我需要在源文件中提供一个实现。
有没有办法在接口文件中获得真正的别名?
答案 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