为什么第一个定义将被拒绝而第二个定义将被接受,最好的直觉是什么?
while
它是否与2种归约方法相关联:每个函数替换(和Rec分隔符)一个规则VS每个函数定义(和lambda提升)一个规则?
答案 0 :(得分:5)
验证递归定义是否有效是一件很难的事。
基本上,您想避免使用这种形式的模式:
let rec x = x
在定义的每个左侧都是函数声明的情况下,您会知道它将很好。最糟糕的是,您正在创建一个无限循环,但至少您正在创建一个值。但是x = x
情况不会产生任何结果,也完全没有语义。
现在,在您的特定情况下,您确实在创建函数(无限循环),但是检查您实际上更难。为了避免编写尝试进行详尽检查的代码,OCaml开发人员决定采用一种更简单的算法。
您可以查看规则here。这是摘录(重点是我的):
如果
expr1
…exprn
中的每个相对于name1
…namen
是静态构造的,则不会立即链接到以下任何一个name1
…namen
,并且不是参数为抽象类型的数组构造器。
如您所见,不允许直接递归变量绑定。
但这不是最终规则,因为对编译器pending release的这一部分进行了改进。我尚未测试您的示例是否通过了测试,但是有一天您的代码可能会被接受。