Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Currying decorator in python

Tags:

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!

like image 872
ElfsЯUs Avatar asked Feb 26 '12 23:02

ElfsЯUs


People also ask

What is Currying in Python?

Currying is the transformation of a function with multiple arguments into a sequence of single-argument functions. That means converting a function like this f(a, b, c, ...) into a function like this f(a)(b)(c)... . If you know Python's functools. partial , then this is very similar to it.

Does Python have Currying?

Python and Curried FunctionsPython does not have an explicit syntax for Currying functions; but it does provide infrastructure that allows Curried functions to be created.

What is decorator used for in Python?

A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.

What is Python Currying function use an example to explain?

Example of Currying function in Pythondef add(a,b,c): return a+b+c print(add(1,2,3)) output : 6. This is a simple example of a function adding 3 numbers, the same code in currying can be written as below def add(a): def w(b): def x(c): print(a+b+c) return x return w add(1)(2)(3)


2 Answers

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)
like image 80
georg Avatar answered Sep 24 '22 13:09

georg


The source code for curry in the toolz library is available at the following link.

https://github.com/pytoolz/toolz/blob/master/toolz/functoolz.py

It handles args, kwargs, builtin functions, and error handling. It even wraps the docstrings back onto the curried object.

like image 26
MRocklin Avatar answered Sep 24 '22 13:09

MRocklin