|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 | #---------------------------------------------------------------curry---
lcurry = lambda func, *args, **kw:\
lambda *p, **n:\
func(*args + p, **dict(kw.items() + n.items()))
# just for esthetics...
curry = lcurry
#--------------------------------------------------------------rcurry---
# NOTE: this adds the curried args to the tail...
rcurry = lambda func, *args, **kw:\
lambda *p, **n:\
func(*p + args, **dict(kw.items() + n.items()))
#--------------------------------------------------------------LCurry---
class LCurry(object):
'''
this is the left curry class.
'''
def __new__(cls, func, *args, **kw):
obj = object.__new__(cls)
if isinstance(func, LCurry) or isinstance(func, RCurry):
obj._curry_func = func._curry_func
obj._curry_args = (func._curry_args[0] + args, func._curry_args[1])
obj._curry_kw = kw = kw.copy()
kw.update(func._curry_kw)
else:
obj._curry_func = func
obj._curry_args = (args, ())
obj._curry_kw = kw.copy()
return obj
def __call__(self, *args, **kw):
self._curry_func(*self._curry_args[0] + args + self._curry_args[1], **dict(self._curry_kw.items() + kw.items()))
# just for esthetics...
Curry = LCurry
#--------------------------------------------------------------RCurry---
class RCurry(object):
'''
this is the right curry class.
'''
def __new__(cls, func, *args, **kw):
obj = object.__new__(cls)
if isinstance(func, LCurry) or isinstance(func, RCurry):
obj._curry_func = func._curry_func
obj._curry_args = (func._curry_args[0] ,func._curry_args[1] + args)
obj._curry_kw = kw = kw.copy()
kw.update(func._curry_kw)
else:
obj._curry_func = func
obj._curry_args = ((), args)
obj._curry_kw = kw.copy()
return obj
def __call__(self, *args, **kw):
self._curry_func(*self._curry_args[0] + args + self._curry_args[1], **dict(self._curry_kw.items() + kw.items()))
#-----------------------------------------------------------------------
|
<pre>most of the things said for the above mentioned recipe apply here as
well, thus reading of that recipe is strongly recommended if you are not
familiar with the curry concept and usage.
as for the reason there are two versions of each curry and rcurry see the
note below.
here are a few examples:
---cut---
def f(*args):
print args
here we use the lambda version...
ff = curry(f, 0)
now for what the classes are for...
fff0 = Curry(f, -1)
fff1 = Curry(fff0, 0)
fff2 = RCurry(fff1, 1)
print ff() # will print "(0,)"
print fff0() # will print "(-1,)"
print fff1() # will print "(-1, 0)"
print fff2() # will print "(-1, 0, 1)"
print fff2('foo') # will print "(-1, 0, 'foo', 1)"
--uncut--
NOTE: though the lambda version is faster and more memory efficient it does
come at a cost, that is, if you use it recursively (as in the class
example above) it will add an extra function call penalty for each
recursion level when the resulting function is called.
</pre>
|