2017-09-26 40 views
0

是否有可能在没有创建“必须实现的新模块”的情况下在mli中模块化。 这个例子很有意思,但是,假设我有以下源文件int_wrapper.ml。OCaml:如何获得模块别名本地mli文件

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

模块的别名必须存在于.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 
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