Z = lambda worker: (lambda x: worker(lambda *args: x(x)(*args)))(lambda x: worker(lambda *args: x(x)(*args)))
fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
def fix1(worker):
return (lambda x: worker(lambda *args: x(x)(*args)))(lambda x: worker(lambda *args: x(x)(*args)))
def fix2(worker):
def left(x):
return worker(lambda *args: x(x)(*args))
def right(x):
return worker(lambda *args: x(x)(*args))
return left(right)
def fix3(worker):
def step(x):
return worker(lambda *args: x(x)(*args))
return step(step)
def fix4(worker):
def step():
def recursor(*args):
return step()(*args)
return worker(recursor)
return step()
def defact(recursor):
def worker(x):
return 1 if x == 0 else x * recursor(x-1)
return worker
print '!', fix4(defact)(5)
#for fp_combinator in reversed((Z, fix1, fix2, fix3, fix4)):
# print fp_combinator.__name__, fp_combinator(defact)(5) == 120