我有一个库是常见的数据类型是在一个只有签名的模块中定义的(将该签名复制到一个实现没有意义,因为它不包含任何功能):
(* b.mli *)
type bar = A of int | B of float
(* a.ml: *)
let foo = function B.A i -> B.A (i+1)
| B.B f -> B.B (f +. 1.)
(* c.mllib *)
A
B
在上面的设置中,ocamlbuild无法创建具有相当令人惊讶的错误的库:
choeger@daishi /tmp/test % ocamlbuild c.cmxa
Solver failed:
Ocamlbuild cannot find or build c.ml. A file with such a name would usually be a source file. I suspect you have given a wrong target name to Ocamlbuild.
我可以在没有在mllib文件中指定B的情况下构建,但是类型栏变为抽象(这不是预期的)。有没有办法使用ocamlbuild包含签名?
答案 0 :(得分:2)
您无法将B
模块打包到库中,因为它不存在。您只编译了接口,但没有编译模块,即编译单元。 cmxa
的目的是成为已编译代码的容器,因为您的B
接口不包含任何代码,因此无法将任何内容放入库中。这意味着,您根本不需要将对模块B的引用放入mllib
文件中。
更常见的方法是将类型和接口放入ml
文件而不使用mli
文件。我认为与仅mli
方法相比,这种方法更好,因为它允许使用类型驱动的代码生成器,例如,仅使用mli
方法,您无法执行以下操作: / p>
type bar = A of int | B of float with sexp
但是,如果您仍希望mli
没有ml
,那么我建议您使用oasis
。它有一个名为pure_interface
的功能,允许您构建此类库。