Currying in Python
Kiuhnm
kiuhnm03.4t.yahoo.it
Fri Mar 16 21:21:32 EDT 2012
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
More information about the Python-list
mailing list