problem with curring in python

Terry Reedy tjreedy at udel.edu
Tue Oct 22 06:02:29 EDT 2019


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


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /