Recently, I have studied 'Programming language' using standard ML, and I've learned currying method(or something), so I applied it in Python. The below is simple function and currying.
def range_new(x, y):
return [i for i in range(x, y+1)]
def curry_2(f):
return lambda x: lambda y: f(x, y)
def uncurry_2(f):
pass # I don't know it...
print(range_new(1, 10))
curried_range = curry_2(range_new)
countup = curried_range(1)
print(countup(10))
print(curried_range(1)(10))
The result is below. And it works well; with curry_2
we can make a new function(countup
). But, then I want to make an uncurried function.
However, I don't know how I can make it.
How can I do it?
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Currying is the transformation of a function with multiple arguments into a sequence of single-argument functions. That means converting a function like this f(a, b, c, ...) into a function like this f(a)(b)(c)... . If you know Python's functools. partial , then this is very similar to it.
uncurry converts a curried function to a function on pairs.
The "currying" is the process of taking the function of multiple arguments and converting it into a serious of functions that each take a single argument and return a function of a single argument, or in the case of the final function, return the actual result.
The easiest solution is to wrap the curried function again with code that uncurries it:
def uncurry_2(f):
return lambda x, y: f(x)(y)
uncurried_range = uncurry_2(curried_range)
print(uncurried_range(1, 10))
It's not exactly good style but you can access the variables in the closure using the (maybe CPython-only) __closure__
attribute of the returned lambda
:
>>> countup.__closure__[0].cell_contents
<function __main__.range_new>
This accesses the content of the innermost closure (the variable used in the innermost lambda
) of your function curry_2
and thus returns the function you used there.
However in production code you shouldn't use that. It would be better to create a class (or function) for currying that supports accessing the uncurried function (which is something lambda
does not provide). However some functools in Python support accessing the "decorated" function, for example partial
:
>>> from functools import partial
>>> countup = partial(range_new, 1)
>>> print(countup(10))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> countup.func
<function __main__.range_new>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With