【发布时间】:2018-08-12 00:05:38
【问题描述】:
我在思考延迟评估的工作原理时遇到了一些问题。我试图用 Y-Combinator 来理解它:
如果我们编写一个简单版本的 Y-Combinator,我们会遇到无限递归的问题:
Ysimple = (lambda f : (lambda x : f(x(x))) (lambda x : f(x(x))))
当我们构建递归函数时,问题出现了:
almost_factorial = lambda f : lambda n : 1 if n == 0 else n * f(n-1)
factorial = Ysimp(almost_factorial) # <- infinite recursion
Ysimple = (lambda f : (lambda x : f(x(x))) (lambda x : f(x(x)) ))
[上一行重复了 995 次以上] RecursionError: 最大值 超出递归深度
但我们可以将第二个或两个f(x(x))-表达式包装在延迟抽象中:
Ydelay = (lambda f : (lambda x : f(x(x))) (lambda x : f(lambda y: x(x)(y))) )
现在代码可以正常工作了。但为什么呢?
如果我们的文件中只有Ysimple,则不会评估任何内容。所以我假设只有 lambdas 被评估为顶级表达式。
我做了一些手动评估步骤,但我看不出延迟发生的原因:
Ysimple F = (lambda f : (lambda x : f(x(x))) (lambda x : f(lambda y: x(x)(y)))) F
-> (lambda x : F(x(x))) (lambda x : F(lambda y: x(x)(y)))
-> F( (lambda x : F(lambda y: x(x)(y))) (lambda x : F(lambda y: x(x)(y))) )
Ydelay F = (lambda f : (lambda x : f(x(x))) (lambda x : f(x(x)))) F
-> (lambda x : F(x(x))) (lambda x : F(x(x)))
-> F( (lambda x : F(x(x))) (lambda x : F(x(x))) )
这里的延迟发生在哪里?在这两种情况下,F 都是顶级表达式,而且在这两种情况下,lambda x 的级别都低于F。延迟lambda y 起什么作用?
编辑:
同样,为什么延迟在这里的第一行是如何工作的:
(lambda x : x(x)) (lambda y: lambda x : x(x)(y))
(lambda x : x(x)) (lambda x: x(x))
【问题讨论】:
标签: python lambda evaluation delayed-execution fixpoint-combinators