【发布时间】:2014-09-12 08:24:42
【问题描述】:
我一直在研究 Y Combinator,我知道它是如何在纸上工作的,但我还不知道如何在编程语言中实现它。
Y组合子的推导如下:
Y(F) = F(Y(F))
# Of course, if we tried to use it, it would never work because the function Y immediately calls itself, leading to infinite recursion.
# Using a little λ-calculus, however, we can wrap the call to Y in a λ-term:
Y(F) = F(λ x.(Y(F))(x))
# Using another construct called the U combinator, we can eliminate the recursive call inside the Y combinator, which, with a couple more transformations gets us to:
Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x)))
他如何将Y(F) 扩展为λ x.(Y(F))(x)?以及他如何使用 U Combinator?
这里是 Javascript 和 Elixir 的实现:
# javascript
var Y = function (F) {
return (function (x) {
return F(function (y) { return (x(x))(y);});
})(function (x) {
return F(function (y) { return (x(x))(y);});
});
};
# elixir
defmodule Combinator do
def fix(f) do
(fn x ->
f.(fn y -> (x.(x)).(y) end)
end).(fn x ->
f.(fn y -> (x.(x)).(y) end)
end)
end
end
如果这是公式:Y = \f.(\x.f(x x))(\x.f(x x)),那么 lambda 表达式中的 f,x 与上面实现中的 f,x,y 之间的关系是什么? x 看起来是同一个 x,f 看起来是同一个 f。那么y是什么?具体来说,为什么 x x 的 lambda 等效项被包装在使用 y 的函数中?
y 有点像函数的参数吗!?
【问题讨论】:
-
您应该观看 Jim Weirich 的 Ruby 函数式编程视频。在演讲中,他一步步推导出 Y Combinator。非常令人印象深刻,教育和有趣的观看! youtube.com/watch?v=FITJMJjASUs
标签: javascript elixir y-combinator