gpt4 book ai didi

mli 文件的模块别名

转载 作者:行者123 更新时间:2023-12-01 14:33:51 25 4
gpt4 key购买 nike

我有以下情况:

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 文件?

备注:我知道实现文件和接口(interface)文件之间的区别,但据我所知,只要接口(interface)只包含类型定义,就不需要实现文件。假设我们将以下模块签名添加到 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 文件的注释。

最佳答案

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

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

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

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

关于mli 文件的模块别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46080978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com