如何使用Y-Combinator;为什么这个无限递归返回9?

时间:2016-08-11 17:18:41

标签: haskell functional-programming y-combinator

Y - Combinator

我一直在努力学习Y - Combinators (对此的解释也很可爱)并且遇到了这个wiki的例子。无论是Haskell还是Python,都会对这个主题进行深入的解释。 Pleaaase!

代码

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

问题

fix应用于9时,名为fix的函数会返回(\x -> 9),我不知道为什么;当我关注堆栈时,我想象f(f ... (fix f) ...)

>> fix (\x -> 9)
>> 9

1 个答案:

答案 0 :(得分:11)

首先:您拥有的fix函数是使用直接递归实现的定点组合 。 Y组合器是特定的定点组合器,不需要语法递归,所以它完成了与fix相同的事情,但是以不同的方式。

如果您有点好奇,可以在这里查看how to implement the Y combinator in Haskell。静态类型有点棘手 - 它需要递归类型才能工作。

至于你的第二个问题,代码的工作原因是懒惰。如果您将(\ x -> 9)应用于任何,则该内容永远不会被评估。试试这个:

λ> (\ x -> 9) (error "fail")
9

这包括fix定义中的递归调用。看看在f的定义中将(\ x -> 9)替换为fix时会发生什么:

(\ x -> 9) (fix f)

遵循与error版本完全相同的逻辑,递归调用永远不会被评估,您只需获得9