Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #21788
| 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) |
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 | Next — Next in thread | Find similar | Unroll 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