让 rec 获取值,让 rec 获取 ocaml 中的函数

Posted

技术标签:

【中文标题】让 rec 获取值,让 rec 获取 ocaml 中的函数【英文标题】:let rec for values and let rec for functions in ocaml 【发布时间】:2019-04-19 13:19:16 【问题描述】:

为什么第一个定义会被拒绝,而第二个定义会被接受,最好的直觉是什么?

let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x

它是否与 2 种归约方法有关:每个函数替换(和 Rec 分隔符)一个规则 VS 每个函数定义一个规则(和 lambda 提升)?

【问题讨论】:

我认为这是由the value restriction 引起的,显式传递参数称为eta 扩展。我不知道如何以任何直观的方式解释这一点。 我也没有。与 haskell 相比,这有点烦人,尽管我确信这样做有很好的理由.. 【参考方案1】:

验证递归定义是否有效是一件非常困难的事情。

基本上,您希望避免这种形式的模式:

let rec x = x

在定义的每个左侧都是函数声明的情况下,你知道它会没事的。在最坏的情况下,您正在创建一个无限循环,但至少您正在创造一个价值。但是x = x 的情况不会产生任何东西,而且完全没有语义。

现在,在您的具体情况下,您确实在创建函数(无限循环),但检查您实际上是不是更难。为了避免编写会尝试详尽检查的代码,OCaml 开发人员决定使用更简单的算法。

您可以了解规则here。这是一段摘录(重点是我的):

如果expr1 ... exprn 中的每一个相对于name1 ... namen 都是静态构造的,则将被接受,没有立即链接到任何name1 ... namen,并且不是其参数具有抽象类型的数组构造函数。

如您所见,直接递归变量绑定是不允许的。

但这不是最终规则,因为编译器pending release 的那部分有改进。我尚未测试您的示例是否通过它,但有一天您的代码可能会被接受。

【讨论】:

以上是关于让 rec 获取值,让 rec 获取 ocaml 中的函数的主要内容,如果未能解决你的问题,请参考以下文章

获取 TypeError:找不到所需的参数“rec”(位置 2)

根据 XSLT 中的特定节点值获取节点

Web测试实践--Rec 2

如何刷回官方的recovery

如何获得一个月的所有天数? [复制]

QT获取字符串的像素的宽与高