【发布时间】:2017-12-22 03:22:38
【问题描述】:
我有以下情况:
mli 文件 ds.mli 只包含一个类型声明:
type t = A of int | B of string
现在我想在另一个模块 user.ml 中为 Ds 创建一个别名:
module D = Ds
在编译时,我从链接器收到以下错误消息:
$ ocamlc ds.mli user.ml
File "user.ml", line 1:
Error: Error while linking user.cmo:
Reference to undefined global `Ds'
如果我将 ds.mli 复制到 ds.ml 并调用
$ ocamlc ds.mli ds.ml user.ml
编译通过。
是否有可能避免创建 ds.ml 文件?
备注: 我知道实现文件和接口文件之间的区别,但据我所知,只要接口只包含类型定义,就不需要实现文件。假设我们将以下模块签名添加到 ds.mli:
module T : sig
type t = C | D
end
然后是用户中bar的定义:
let bar = function
| Ds.T.C -> true
| Ds.T.D -> false
通过
编译没有问题$ ocamlc ds.mli user.ml
将别名扩展到签名应该不是问题。
编辑: 忘记将 ds.ml 添加到第二个 ocamlc 调用的参数中。 编辑:添加了关于使用 mli 文件的备注。
【问题讨论】:
-
不,
mli文件实际上不能定义除签名之外的任何内容,您需要使用ml文件来实现它们 -
这让我很困惑——我的 mli 文件只包含一个类型(签名)。通过
match x with | Ds.A i -> i直接引用它就像一个魅力。只有当我创建模块别名时,我才突然需要一个用于创建 ds.cmo 的实现文件。 -
如果你的模块类型只包含公共类型签名,它不需要实现,因为没有什么要实现的。但这并不意味着它也可以作为一个模块使用。