Currying decorator in python

ElfsЯUs picture ElfsЯUs · Feb 27, 2012 · Viewed 7.7k times · Source

I am trying to write a currying decorator in python, and I think I've got the general idea down, but still got some cases that aren't working right...

def curry(fun):

    cache = []
    numargs = fun.func_code.co_argcount

    def new_fun(*args, **kwargs):
        print args
        print kwargs
        cache.extend(list(args))

        if len(cache) >= numargs:   # easier to do it explicitly than with exceptions

            temp = []
            for _ in xrange(numargs):
                temp.append(cache.pop())
            fun(*temp)

    return new_fun


@curry
def myfun(a,b):
    print a,b

While for the following case this works fine:

myfun(5)
myfun(5)

For the following case it fails:

myfun(6)(7)

Any pointers on how to correctly do this would be greatly appreciated!

Thanks!

Answer

georg picture georg · Feb 27, 2012

The below implementation is naive, google for "currying python" for more accurate examples.

def curry(x, argc=None):
    if argc is None:
        argc = x.func_code.co_argcount
    def p(*a):
        if len(a) == argc:
            return x(*a)
        def q(*b):
            return x(*(a + b))
        return curry(q, argc - len(a))
    return p

@curry
def myfun(a,b,c):
    print '%d-%d-%d' % (a,b,c)



myfun(11,22,33)
myfun(44,55)(66)
myfun(77)(88)(99)