カリー化デコレータ
Python のデコレータはなかなか面白い機能だと思ったので、試しにカリー化を実装してみました。
@curry def f(x,y,z): ...
などと書くと、カリー化されたfが定義されます。まぁ functools.partial があれば全然必要無いシロモノではあるのですが。
複数まとめて関数適用するとき f(x)(y)(z) とか気持ち悪いので、f.apply(x,y,z) みたいに普通っぽく呼び出せるようにもなっています。
可変長引数とは相性悪いです(*付き引数=引数1個ぶんとして扱われます)。
def arity_of(f): return len(f.func_code.co_varnames) class curry: def __init__(self, f, n=None, args=None): self.func = f self.arity = n if n != None else arity_of(f) self.args = args # linked list def __call__(self, x): f = curry(self.func, self.arity-1, (x, self.args)) if f.arity <= 0: return f.__apply_args() else: return f def __apply_args(self): args = [] l = self.args while l != None: args.append(l[0]) l = l[1] return self.func(*reversed(args)) def apply(self, *args): f = self for x in args: f = f(x) return f if __name__=='__main__': @curry def test(x, y, z): print x, y, z return x + y * z print test(1)(2)(3) print test.apply(1,2,3) f = test(1) g = test.apply(1,2) print f.apply(2,3) print g(3)