On 10/22/2019 4:58 AM, Antoon Pardon wrote:
Using python 3.5
I have been experimenting with curried functions. A bit like in Haskell.
So I can write the following function:
def sum4(a, b, c, d):
return a + b + c + d
summing = curry(sum4)
print summing(1)(2)(3)(4) # this prints 10.
The problem is I need the signature of the original function in order to
know when to finally call the function and return the actual result.
However buildin functions don't have a
I believe most do.
>>> help(abs)
Help on built-in function abs in module builtins:
abs(x, /)
Return the absolute value of the argument.
>>> abs.__text_signature__
'($module, x, /)'
>>> import inspect
>>> inspect.signature(abs)
<Signature (x, /)>
The exceptions are those with complicated signatures still given in
multiple lines in the docstring since the true signature would be too
complicated for humans to digest. Example:
>>> help(bytes)
Help on class bytes in module builtins:
class bytes(object)
| bytes(iterable_of_ints) -> bytes
| bytes(string, encoding[, errors]) -> bytes
| bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
| bytes(int) -> bytes object of size given by the parameter
initialized with null bytes
| bytes() -> empty bytes object
The latter 5 lines are from bytes.__doc__. signature(bytes) raises
ValueError. Note that parameter 1 is the union of 4 types, 3
iterable_of_ints, bytes_or_buffer, int, and string (str_or_bytes), 2 of
which are unions themselves and 2 of which are non-disjoint.
Furthermore, the presence of 1 or 2 more args is only valid if the 1st
arg is a string. The concept of currying does not really apply to this
situation very well.
In other words, the cases without signatures should probably not be curried.
signature. Here below is my
current experimental implementation. Any ideas for an other approach?
def curry(func, *args):
arg_len = len(signature(func).parameters)
if arg_len <= len(args):
return func(*args)
else:
return CurryType(func, arg_len, args)
class CurryType:
def __init__(self, func, arg_len, args):
self.func = func
self.arg_len = arg_len
self.args = list(args)
def __call__(self, *args):
args = self.args + list(args)
if self.arg_len <= len(args):
return self.func(*args)
else:
return CurryType(self.func, self.arg_len, args)
--
Terry Jan Reedy
--
https://mail.python.org/mailman/listinfo/python-list