Python currying with any number of variables

I am trying to use currying to make a simple functional add in Python. I found this curry decorator here .

def curry(func):     
    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

@curry
def foo(a, b, c):
    return a + b + c

Now this is great because I can make some simple curries:

>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6

But this only works for exactly three variables. How to write the function foo so that it can accept any number of variables and still be able to curry the result? I tried a simple solution to use * args, but that did not work.

Edit: I looked at the answers, but still cannot figure out how to write a function that can work, as shown below:

>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6
>>> foo(1)(2)
3
>>> foo(1)(2)(3)(4)
10
+4
source share
3 answers

, explicit is better than implicit:

from functools import partial

def example(*args):
    print("This is an example function that was passed:", args)

one_bound = partial(example, 1)
two_bound = partial(one_bound, 2)
two_bound(3)

@JohnKugelman , - curried " " " ". , Haskell ( ), , , , " x, 3" " " " 3". . (, , " ", special cases aren't special enough , .)

functools.partial - Python. , partial "curried" ( partial ). ; , , .

+5

, functools.partial :

def curry (prior, *additional):
    def curried(*args):
        return prior(*(args + additional))
    return curried

def add(*args):
    return sum(args)

x = curry(add, 3,4,5)
y = curry(b, 100)
print y(200)
# 312

curry factory, ; , , , factory - , .

, add curry, add(1) -: factory <callable>, *<args>. .

+1

FACT 1: it is simply not possible to implement an automatic currying function for a variational function.

FACT 2: You may not be looking for curry if you want the function to be passed to her * in order to know * that it will depend on to make her behave differently.

In case you need a way to curry a variative function, you should go with something next to these lines below (using your own cut off):

def curryN(arity, func):
    """curries a function with a pre-determined number of arguments"""
    def curried(*args, **kwargs):
        if len(args) + len(kwargs) >= arity:
            return func(*args, **kwargs)
        return (lambda *args2, **kwargs2:
            curried(*(args + args2), **dict(kwargs, **kwargs2)))
    return curried

def curry(func):
    """automatically curries a function"""
    return curryN(func.__code__.co_argcount, func);

this way you can:

def summation(*numbers):
    return sum(numbers);

sum_two_numbers = curryN(2, summation)
sum_three_numbers = curryN(3, summation)
increment = curryN(2, summation)(1)
decrement = curryN(2, summation)(-1)
0
source

Source: https://habr.com/ru/post/1650382/


All Articles