gpt4 book ai didi

ocaml - OCaml 中的仿函数 : triple code duplication necessary?

转载 作者:行者123 更新时间:2023-12-04 15:11:31 24 4
gpt4 key购买 nike

我想澄清一点:目前在我看来,在声明仿函数时需要重复三重签名,前提是我们将其导出到 .mli 文件中。这是一个例子:

假设我们有一个仿函数 Make , 它产生一个模块 A参数化 SigA (我能想到的最简单的例子)。因此,在 .mli 文件中,我们有:

module type A = sig
type a
val identity : a -> a
end

module type SigA = sig
type a
end

module Make (MA:SigA) :
A with type a := MA.a

现在我明白我们必须在 .ml 文件中编写一个实现:
module Make (MA:SigA) = struct
type a = MA.a

let identity obj = obj
end

到目前为止一切顺利,对吧?不!原来我们必须复制 A 的声明和 SigA逐字写入 .ml 文件:
module type A = sig
type a

val identity : a -> a
end

module type SigA = sig
type a
end

module Make (MA:SigA) = struct
type a = MA.a

let identity obj = obj
end

虽然我(模糊地)理解复制 SigA 背后的基本原理(毕竟源码中提到过),复制 A定义对我来说似乎是一个完全没有意义的练习。
我已经简要浏览了 Core 代码库,他们似乎只是将其复制到小模块和更大的模块,一旦将其导出到单独的 .mli,该 .mli 既可用于 .ml 也可用于 .mli。

那么这只是一种状态吗?每个人都可以复制模块签名三次吗(一次在 .mli 文件中,两次在 .ml 文件中:声明和定义!!)
目前我正在考虑完全放弃 .mli 文件并使用 .ml 文件中的签名限制模块导出。

编辑:是的,我知道我可以通过声明 A 的接口(interface)来避免这个问题。内联 Make在 .mli 文件中。但是,如果我想从该模块外部使用该接口(interface),这对我没有帮助。

最佳答案

这是因为一对 ML 和 MLI 文件就像一个结构和与之匹配的相应签名。

避免两次写出模块类型的常用方法是在单独的 ML 文件中定义它。例如,

(* sig.ml *)
module type A = sig
type a
end

module type B = sig
type b
val identity : b -> b
end

(* make.mli *)
module Make (A : Sig.A) : Sig.B with type b = A.a

(* make.ml *)
module Make (A : Sig.A) =
struct
type b = A.a
let identity x = x
end

如果 MLI 文件不隐藏任何内容,则可以省略它,例如 Sig。上面的模块。

在其他情况下,将签名与实现分开写出是一个特性,而不是真正的重复——它定义了模块的导出,通常是实现中的一小部分。

关于ocaml - OCaml 中的仿函数 : triple code duplication necessary?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22348341/

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