为什么我们不能用 Opal 中使用 <~> 的代码替换 "many" 的 def?

Why can't we replace the def of "many" with the code using <~> in Opal?

我有一个关于 https://github.com/pyrocat101/opal/blob/master/opal.ml 的问题。

在第 105 行,我将 many 的定义替换为 let rec many x = option [] (x <~> many x);;。然后,我收到以下错误消息:

Stack overflow during evaluation (looping recursion?).

但是,这两个代码似乎是一样的。为什么?

我使用的是 OCaml 版本 4.12.0。

OCaml 是一种热切的语言。因此在

let rec many x = option [] (x <~> many x)

一旦提供了参数 x,内部表达式 many x 就会被完全计算。因此,评估 many x 需要评估 many x 和函数循环。 最小的修复是避免隐藏 many:

的输入参数
let rec many x input = option [] (x <~> many x) input

(换句话说,point-free 风格在急切且可变的语言中并不是无后果的。) 由于内部 many x 在这里是一个闭包,它的执行将被暂停以打破循环。

同理,内联版本

let rec many x = option [] (x >>= fun r -> many x >>= fun rs -> return (r :: rs))

通过在匿名函数 fun r -> ....

中移动内部表达式 many x 来获得相同的结果