6

我最近偶然发现了这篇文章,它描述了如何在 Ruby 中只使用 Procs 来编写 FizzBu​​zz,由于我很无聊,我认为尝试在 Python 中使用 lambdas 实现同样的东西会很好。

我到了使用嵌套函数创建数字的部分,并编写了以下 Python 脚本:

#!/usr/bin/env python

zero  = lambda p : (lambda x: x)
one   = lambda p : (lambda x: p(x))
two   = lambda p : (lambda x: p(p(x)))
three = lambda p : (lambda x: p(p(p(x))))
five  = lambda p: (lambda x: p(p(p(p(p(x))))))

fifteen = lambda p : (lambda x: p(p(p(p(p( \
                                p(p(p(p(p( \
                                p(p(p(p(p(x))))))))))))))))


hundred = lambda p: (lambda x: p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p(x)))))))))))))))))))))))))))) \
                                                     ))))))))))))))))))))))))))) \
                                                     ))))))))))))))))))))))))))) \
                                                     )))))))))))))))))))

def to_int(func):
    return func(lambda n: n + 1)(0)

print to_int(zero)
print to_int(one)
print to_int(two)
print to_int(three)
print to_int(five)
print to_int(fifteen)
print to_int(hundred)

数字 0 到 15 可以正常工作,但如果我尝试创建数字 100,由于以下错误,文件将无法运行:

s_push:解析器堆栈溢出
MemoryError

我必须将其注释掉才能使文件完全运行。

这种很糟糕——有什么办法可以绕过这个限制,这样我就可以任意嵌套 lambdas 和函数调用,而不会导致 Python 崩溃和内存不足?

或者,是否有某种 lambda 演算技巧可以用来表达数字 100,而无需太多嵌套函数?

4

3 回答 3

9

在没有这么多嵌套函数的情况下表达数字 100?

干得好:

>>> test = lambda f: f(lambda x: x + 1)(0)
>>> z = lambda f: lambda x: x
>>> test(z)
0
>>> succ = lambda n: lambda f: lambda x: f(n(f)(x))
>>> _1 = succ(z)
>>> test(_1)
1
>>> _2 = succ(_1)
>>> test(_2)
2
>>> plus = lambda m: lambda n: lambda f: lambda x: m(f)(n(f)(x))
>>> _3 = plus(_1)(_2)
>>> test(_3)
3
>>> mult = lambda m: lambda n: lambda f: lambda x: m(n(f))(x)
>>> _6 = mult(_2)(_3)
>>> test(_6)
6
>>> _5 = plus(_2)(_3)
>>> _25 = mult(_5)(_5)
>>> _4 = plus(_2)(_2)
>>> _100 = mult(_25)(_4)
>>> test(_100)
100
>>> 
于 2012-10-22T08:20:30.310 回答
7

看起来如果不重新编译 Python 是不可能的。解析器堆栈大小使用常量 MAXSTACK in 设置parser.h。您可以增加此值并重新编译以增加限制。请参阅http://bugs.python.org/issue3971http://mail.python.org/pipermail/python-list/2012-March/621555.html

于 2012-10-22T06:11:28.857 回答
2

从 lambda 演算的角度来看,可以使用以下函数来增加数字:

succ = lambda n: lambda p: lambda x: p(n(p)(x))

然后,one = succ(zero)two = succ(one),等等。

于 2012-10-22T07:01:28.753 回答