如何使用 Y-Combinator;为什么这个无限递归return 9?
How to use Y- Combinator; why does this infinite recursion return 9?
Y - 组合器
我一直在尝试了解 Y - Combinators (对此的解释也很好) 并从这个 wiki 中找到了一个例子。在 Haskell 或 Python 中,将非常感谢对该主题的深入解释。请!
代码
fix :: (a -> a) -> a
fix f = f (fix f)
问题
函数调用fix
returns 9
当 fix
应用于 (\x -> 9)
时,我不知道为什么;当我跟随堆栈时,我想象 f(f ... (fix f) ...)
.
>> fix (\x -> 9)
>> 9
首先:您拥有的 fix
函数是一个定点组合器 通过直接递归 实现的。 Y组合器是一个特殊的定点组合器,不需要句法递归所以它完成了与fix
相同的事情但是在另一种方式。
如果您好奇,可以在此处查看 how to implement the Y combinator in Haskell。静态类型有点棘手——它需要递归类型才能工作。
关于你的第二个问题,由于懒惰,代码可以工作。如果你将 (\ x -> 9)
应用到 任何东西 ,那东西将永远不会被评估。试试这个:
λ> (\ x -> 9) (error "fail")
9
这包括fix
定义中的递归调用。看看在 fix
:
的定义中用 (\ x -> 9)
替换最外层的 f
会发生什么
(\ x -> 9) (fix f)
遵循与 error
版本完全相同的逻辑,递归调用 永远不会被计算,你只会得到一个 9
。
Y - 组合器
我一直在尝试了解 Y - Combinators (对此的解释也很好) 并从这个 wiki 中找到了一个例子。在 Haskell 或 Python 中,将非常感谢对该主题的深入解释。请!
代码
fix :: (a -> a) -> a
fix f = f (fix f)
问题
函数调用fix
returns 9
当 fix
应用于 (\x -> 9)
时,我不知道为什么;当我跟随堆栈时,我想象 f(f ... (fix f) ...)
.
>> fix (\x -> 9)
>> 9
首先:您拥有的 fix
函数是一个定点组合器 通过直接递归 实现的。 Y组合器是一个特殊的定点组合器,不需要句法递归所以它完成了与fix
相同的事情但是在另一种方式。
如果您好奇,可以在此处查看 how to implement the Y combinator in Haskell。静态类型有点棘手——它需要递归类型才能工作。
关于你的第二个问题,由于懒惰,代码可以工作。如果你将 (\ x -> 9)
应用到 任何东西 ,那东西将永远不会被评估。试试这个:
λ> (\ x -> 9) (error "fail")
9
这包括fix
定义中的递归调用。看看在 fix
:
(\ x -> 9)
替换最外层的 f
会发生什么
(\ x -> 9) (fix f)
遵循与 error
版本完全相同的逻辑,递归调用 永远不会被计算,你只会得到一个 9
。