Skip to content

Instantly share code, notes, and snippets.

@jirutka
Forked from JulienPalard/curry.py
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jirutka/4681997e12a21cebb1df to your computer and use it in GitHub Desktop.
Save jirutka/4681997e12a21cebb1df to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
def curry(func):
"""
Decorator to curry a function, typical usage:
>>> @curry
... def foo(a, b, c):
... return a + b + c
The function still work normally:
>>> foo(1, 2, 3)
6
And in various curried forms:
>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6
This also work with named arguments:
>>> foo(a=1)(b=2)(c=3)
6
>>> foo(b=1)(c=2)(a=3)
6
>>> foo(a=1, b=2)(c=3)
6
>>> foo(a=1)(b=2, c=3)
6
And you may also change your mind on named arguments,
But I don't know why you may want to do that:
>>> foo(a=1, b=0)(b=2, c=3)
6
Finally, if you give more parameters than expected, the exception
is the expected one, not some garbage produced by the currying
mechanism:
>>> foo(1, 2)(3, 4)
Traceback (most recent call last):
...
TypeError: foo() takes exactly 3 arguments (4 given)
"""
def curried(*args, **kwargs):
if len(args) + len(kwargs) >= func.__code__.co_argcount:
return func(*args, **kwargs)
return (lambda *args2, **kwargs2:
curried(*(args + args2), **dict(kwargs, **kwargs2)))
return curried
if __name__ == "__main__":
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment