在库中包含签名 (.mli) 文件

Include signature (.mli) file in library

我有一个库,通用数据类型是在仅签名模块中定义的(将该签名复制到实现没有意义,因为它不包含任何功能):

(* 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 的情况下进行构建,但随后类型 bar 变得抽象(这不是预期的)。有什么方法可以使用 ocamlbuild 包含 signature 吗?

您无法将 B 模块打包到库中,因为它不存在。您只有编译接口,但没有编译模块,即编译单元。 cmxa 的目的是成为已编译代码的容器,因为您的 B 接口不包含任何代码,因此无法将任何内容放入库中。这意味着,您根本不需要将对模块 B 的引用放入 mllib 文件中。

一种更常见的方法是将类型和接口放入 ml 文件中,而不是 mli。我认为与 mli only 方法相比,这种方法更好,因为它允许使用类型驱动的代码生成器,例如,使用 mli only 方法你不能执行以下操作:

type bar = A of int | B of float with sexp

但是,如果您仍然想要一个没有 mlmli,那么我建议您使用 oasis。它有一个名为 pure_interface 的功能,允许您构建此类库。