只能用非严格评估的语言输入 fix 吗?

3 recursion haskell typechecking unification fixpoint-combinators

我为 Javascript 编写了一个运行时类型检查器,但无法输入fix

fix :: (a -> a) -> a
fix f = ...

fix (\rec n -> if n == 0 then 1 else n * rec (n-1)) 5 -- 120
Run Code Online (Sandbox Code Playgroud)

传递给的阶乘函数fix具有简化类型(Int -> Int) -> Int -> Int

当我尝试在 Javascript 中重现表达式时,我的类型检查器由于无效约束而失败Int ~ Int -> Int

fix (const "hallo") 也失败了,类型检查器抱怨它不能构造一个无限类型(否定发生检查)。

对于其他组合器,我的统一结果与 Haskell 一致。

我的统一算法可能是错误的还是fix只能在非严格环境中输入?

[编辑]

fix在 Javascript 中的实现是const fix = f => f(f).

And*_*ács 5

这是类型检查器中的一个错误。

尽管fixJavascript 中不成熟的 Haskell 定义确实没有终止:

> fix = (f) => f(fix(f))
> factf = (f) => (n) => (n === 0) ? 1 : n * f(n - 1)
> fact = fix(factf) // stack overflow
Run Code Online (Sandbox Code Playgroud)

您必须使用 eta-expanded 定义以防止循环评估fix(f)

> fix = (f) => (a) => f(fix(f), a)
> factf = (f, a) => (a == 0) ? 1 : a * f(a - 1)
> fact = fix(factf)
> fact(10) // prints 3628800
Run Code Online (Sandbox Code Playgroud)