我撤消了 lambda,只是为了使其更易于阅读。下面是使用嵌套函数的代码:
def f1(f):
def f2(a):
return a(a)
def f3(b):
def f4(*args):
return b(b)(*args)
return f(f4)
return f2(f3)
这基本上相当于:
f1 = lambda f: (lambda a: a(a))(lambda b: f(lambda *args: b(b)(*args)))
现在让我们关注函数调用。首先,您将使用一些参数调用 f1。然后会发生以下情况:
- f2 被 f3 调用
- f2 返回以自身为参数调用的 f3
- 现在我们在 f3 里面,b 是 f3
- f3 以 f4 为参数返回 f(你调用 f1 的参数)
- f 是一个回调,它以函数作为其唯一参数调用
- 如果 f 调用此函数,则其调用将应用于 b 调用 b 的结果。 b 是 f3,所以 f 本质上是调用 f3(f3) 的结果,这就是 f 将要返回的结果
因此 f1 可以简化为:
def f1(f):
def f3():
def f4(*args):
return f3()(*args)
return f(f4)
return f3()
现在我想出了一种调用 f1 的方法,它不会以无限递归结束:
called = False
def g1(func):
def g2(*args):
print args
return None
global called
if not called:
called = True
func(5)
else:
return g2
f1(g1) # prints "(5,)"
如您所见,它使用全局来停止递归。
这是另一个示例,它使用 10 的 lambda(lambda 是泊松分布的参数,而不是 lambda 算子)运行泊松分布试验:
import random
def g3(func):
def g4(a):
def g5(b):
print a
return a+b
return g5
if random.random() < 0.1:
return g4(1)
else:
return g4(func(1))
f1(g3)
最后是确定性的,不依赖于全局,实际上有点有趣:
def g6(func):
def g7(n):
if n > 0:
return n*func(n-1)
else:
return 1
return g7
print f1(g6)(5) # 120
print f1(g6)(6) # 720
我相信每个人都可以猜到这个函数是什么,但很有趣的是,你实际上可以让这个奇怪的 lambda 表达式做一些有用的事情。