gpt4 book ai didi

recursion - OCaml:是否可以在单独的文件中定义相互递归的数据结构

转载 作者:行者123 更新时间:2023-12-04 14:23:58 25 4
gpt4 key购买 nike

我是 OCaml 的初学者。
我想知道如何在单独的文件中定义相互递归的数据类型。

我知道以下程序是合法的。

type t1 = A of int | B of t2
and t2 = C of float | C of t1

现在,我想定义这个 t1t2在其他文件中以提高可读性(因为单独需要很多 util 函数)。

我也知道,我可以定义 t1t2如上所述,通过制作 .mli文件并隐藏实现细节(只需在 type t1 文件中写入 type t2.mli)。

但是,现在我不想隐藏它们。
有谁知道该怎么做?

我希望简单的解决方案(不要使用复杂的或魔术的......)。

最佳答案

在当前的 OCaml 实现中,编译单元依赖图必须是非循环的。更简单地说,编译单元(即不同的文件)不能相互递归地相互引用。

这个限制是一个过度近似,因为它不允许有效的程序,并且它与直觉相矛盾,因为可以在单个编译单元中编写递归模块。这种限制的原因来自于递归模块类型检查的复杂性。递归模块不能作为独立实体进行类型检查,因为它需要递归中涉及的整个模块集。但是 OCaml 单独的编译系统要求每个编译单元都是独立的和可键入的。如果 OCaml 不使用单独的编译(并将程序作为一个整体链接),那么就有可能实现递归单元。

部分解决方案是将独立于相互递归的接口(interface)部分分解并在单独的模块中实现它们。例如,您可以按如下方式定义您的类型:

type 'b a = A of int | B of 'b
type 'a c = C of float | C of 'a
type t1 = t2 a and t2 = t1 c

现在您可以为 'b a 定义接口(interface)的非循环部分。这个接口(interface)对于 'b 类型变量应该是通用的(换句话说,它不应该接触它)。在我们的示例中,很难想象这样的接口(interface),但是,假设示例是合成的,但是对于产品类型,此方法将是有意义的(参见 type 'b a = {a : int; b : 'b } - 您可以实现与 a 字段相关的所有功能)。

作为最后一点,我想说递归模块在实践中很少需要,并且通常表示设计中存在问题。特别是,当需要在单独的模块中移动定义时——这表明没有正确选择抽象。当然,可能的情况是,潜在的问题本质上是复杂的,但这在现实生活中非常罕见。

关于recursion - OCaml:是否可以在单独的文件中定义相互递归的数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42395707/

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