斐波纳契上的U组合器:你如何将这段代码翻译成python?

时间:2010-06-22 21:05:20

标签: python fixed-point combinators code-translation

我正在尝试了解组合器,我无法理解(Y overriding self-application)给出的示例。我想我开始掌握这个概念,但我还远未理解。

我想将以下代码翻译成Python:

     (define (U f) (f f))

     (define (fib-nr f)
       (lambda (n)
         (if (< n 2) 1 (+ ((f f) (- n 1)) ((f f) (- n 2))))))

     # Usage:   
     ((U fib-nr) 35) ;==> 14930352

我写了一个'文字'翻译:

U = lambda u: u(u)

def fibnr(f):
    return lambda n:  1 if (n<2) else (f (f (n-1))) + (f (f (n-2)))

但是这不起作用(我认为它与在lambda中评估函数的顺序有关。)

所以我尝试使用函数组合:

# http://code.activestate.com/recipes/52902-function-composition/
class compose:
    '''compose functions. compose(f,g,x...)(y...) = f(g(y...),x...))'''
    def __init__(self, f, g, *args, **kwargs):
        self.f = f
        self.g = g
        self.pending = args[:]
        self.kwargs = kwargs.copy()

    def __call__(self, *args, **kwargs):
        return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs)


U = lambda u: compose(u, u)

def fibnr(f):
    ff = compose(f, f)
    return lambda n:  1 if (n<2) else (ff (n-1)) + (ff (n-2))

但是仍然无法正常工作,在调用我的最后一段代码时,我得到了一个lambda:

>>> U(fibnr)(35)
<function <lambda> at 0x01A1B6B0>

那么,是否可以在Python中编写给定示例的“文字”翻译?我怎么能这样做?

1 个答案:

答案 0 :(得分:3)

我写了一个简单的翻译,似乎可以产生正确的结果:

def U(f): return f(f)

def fibnr(f):
    def lam(n):
        if (n < 2): return 1
        return f(f)(n-1) + f(f)(n-2)
    return lam

或者如果你真的喜欢lambdas:

def fibnr(f): return lambda n: 1 if (n < 2) else f(f)(n-1) + f(f)(n-2)

我认为您最初的问题是将Lisp ((f f) x)转换为Python f(f(x))而不是f(f)(x)

好运了解组合器:)