在库中包含签名 (.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
但是,如果您仍然想要一个没有 ml
的 mli
,那么我建议您使用 oasis
。它有一个名为 pure_interface
的功能,允许您构建此类库。
我有一个库,通用数据类型是在仅签名模块中定义的(将该签名复制到实现没有意义,因为它不包含任何功能):
(* 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
但是,如果您仍然想要一个没有 ml
的 mli
,那么我建议您使用 oasis
。它有一个名为 pure_interface
的功能,允许您构建此类库。