Module mli文件的模块别名

Module mli文件的模块别名,module,ocaml,alias,Module,Ocaml,Alias,我有以下情况: 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' 如

我有以下情况:

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
然后,用户中的条形图定义:

let bar = function
  | Ds.T.C -> true
  | Ds.T.D -> false
通过

$ ocamlc ds.mli user.ml
将别名扩展到签名不应该是问题所在

编辑:忘记将ds.ml添加到第二个ocamlc调用的参数中。
编辑:添加了关于使用mli文件的备注。

类型t=A | B
在一个文件中,
m.ml
基本上与
模块M=结构类型t=A | B端
。 文件
m.mli
中的同一行对应于
模块M:sig类型t=A | B端
前者实现了一个模块。后者只是一个模块签名

签名可用于声明类型,但更常见的是,它用于向外界屏蔽模块实现的某些部分。签名从未实际实现模块,即使模块仅包含类型声明

模块就像一个值,而不是一个类型。例如,模块可以作为语言(“一级模块”)中的值进行包装和操作,也可以作为模块语言中的函子的参数使用


功能栏仅与存在的.mli文件一起工作的事实与此并不矛盾;它是类型上的模式匹配,定义函数时不需要存在类型的值。如果您在user中添加了类似于
let c=Ds.T.c
的内容,那么您已经构造了这样一个值,但这发生在
user.ml
实现文件中

module D = Ds
在这里,你试图将一个模块类型“影响”到一个模块,这是不会发生的

但是,您可以对模块类型执行相同的操作:

module type D = module type of Ds

不,除了签名之外,
mli
文件本身实际上不能定义任何东西,您需要用
ml
文件实现它们,这让我感到困惑-我的mli文件只包含一个类型(签名)。通过
match x with | Ds.A i->i
直接引用它就像一个符咒。只有在创建模块别名时,我才突然需要一个用于创建ds.cmo的实现文件。如果您的模块类型仅包含公共类型签名,则不需要实现,因为没有什么要实现的。但这并不意味着它也可以作为一个模块使用。你可以使用类型定义而不需要实现文件,请参阅我在更新问题中的备注。错误消息表示链接器需要对象文件(从实现创建)。我假设它背后有工程方面的原因,来自别名的间接作用。但我的问题是,我是否可以绕过这个问题,或者我是否需要将复制作为.ml文件:-)(这就是为什么我给出+1作为答案,但不接受它作为解决方案)嗯,我不知道ds.mli文件如何满足需要。但是你可以用另一种方法:只创建一个具有相同内容的ds.ml文件。然后签名被自动推断,没有重复?这就是我最后要做的。我只是在阅读模块类型,但是当我用D替换函数栏中的Ds时,我得到了一个未绑定的模块错误(对于D)。我想我现在需要做更多的事情?嗯,它仍然是一个模块类型,而不是一个模块。