Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #21788

Currying in Python

Date 2012-03-17 02:21 +0100
From Kiuhnm <kiuhnm03.4t.yahoo.it>
Newsgroups comp.lang.python
Subject Currying in Python
Message-ID <4f63e724$0$1386$4fafbaef@reader1.news.tin.it> (permalink)
Organization TIN.IT (http://www.tin.it)

Show all headers | View raw


Here we go.

--->
def genCur(f, unique = True, minArgs = -1):
    """ Generates a 'curried' version of a function. """
    def geng(curArgs, curKwargs):
        def g(*args, **kwargs):
            nonlocal f, curArgs, curKwargs, minArgs;    # our STATIC data

            if len(args) or len(kwargs):
                # Allocates data for the next 'g'. We don't want to modify our
                # static data.
                newArgs = curArgs[:];
                newKwargs = dict.copy(curKwargs);

                # Adds positional arguments.
                newArgs += args;

                # Adds/updates keyword arguments.
                if unique:
                    # We don't want repeated keyword arguments.
                    for k in kwargs.keys():
                        if k in newKwargs:
                            raise(Exception("Repeated kw arg while unique = True"));
                newKwargs.update(kwargs);

                # Checks whether it's time to evaluate f.
                if minArgs >= 0 and minArgs <= len(newArgs) + len(newKwargs):
                    return f(*newArgs, **newKwargs);    # f has enough args
                else:
                    return geng(newArgs, newKwargs);    # f needs some more args
            else:
                return f(*curArgs, **curKwargs);    # the caller forced the evaluation
        return g;
    return geng([], {});

def cur(f, minArgs = -1):
    return genCur(f, True, minArgs);

def curr(f, minArgs = -1):
    return genCur(f, False, minArgs);

# Simple Function.
def f(a, b, c, d, e, f, g = 100):
    print(a, b, c, d, e, f, g);

# NOTE: '<====' means "this line prints to the screen".

# Example 1.
c1 = cur(f)(1);
c2 = c1(2, d = 4);              # Note that c is still unbound
c3 = c2(3)(f = 6)(e = 5);       # now c = 3
c3();                           # () forces the evaluation              <====
c4 = c2(30)(f = 60)(e = 50);    # now c = 30
c4();                           # () forces the evaluation              <====

print("\n------\n");

# Example 2.
c1 = curr(f)(1, 2)(3, 4);           # curr = cur with possibly repeated
                                    # keyword args
c2 = c1(e = 5)(f = 6)(e = 10)();    # ops... we repeated 'e' because we <====
                                    # changed our mind about it!
                                    # again, () forces the evaluation

print("\n------\n");

# Example 3.
c1 = cur(f, 6);             # forces the evaluation after 6 arguments
c2 = c1(1, 2, 3);           # num args = 3
c3 = c2(4, f = 6);          # num args = 5
c4 = c3(5);                 # num args = 6 ==> evalution                <====
c5 = c3(5, g = -1);         # num args = 7 ==> evaluation               <====
                            # we can specify more than 6 arguments, but
                            # 6 are enough to force the evaluation

print("\n------\n");

# Example 4.
def printTree(func, level = -1):
    if level == -1:
        printTree(cur(func), level + 1);
    elif level == 6:
        func(g = '')();     # or just func('')()
    else:
        printTree(func(0), level + 1);
        printTree(func(1), level + 1);

printTree(f);

print("\n------\n");

def f2(*args):
    print(", ".join(["%3d"%(x) for x in args]));

def stress(f, n):
    if n: stress(f(n), n - 1)
    else: f();          # enough is enough

stress(cur(f2), 100);
<---

Kiuhnm

Back to comp.lang.python | Previous | NextNext in thread | Find similar | Unroll thread


Thread

Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-17 02:21 +0100
  Re: Currying in Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-03-17 01:46 +0000
    Re: Currying in Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-03-17 02:14 +0000
  Re: Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-19 00:49 +0100
  Re: Currying in Python Ian Kelly <ian.g.kelly@gmail.com> - 2012-03-19 17:20 -0600
    Re: Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-20 01:24 +0100
    Re: Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-20 02:13 +0100
    Re: Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-20 11:06 +0100
  Re: Currying in Python Arnaud Delobelle <arnodel@gmail.com> - 2012-03-20 07:11 +0000
    Re: Currying in Python Kiuhnm <kiuhnm03.4t.yahoo.it> - 2012-03-20 11:13 +0100

csiph-web