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

Reply via email to