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!
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.
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.
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.
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)
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With