Closed
Description
It should not be too hard. partial
was pretty much ok, and @curry
can reuse a lot of existing stuff.
It should work like so:
from returns.curry import curry
@curry
def sum_two(a: int, b: int) -> int:
return a + b
assert sum_two(2)(3) == 5
assert sum_two(2, 3)() == 5
Internally we can analyse @curry
calls and split function definition into multiple Overloaded
cases like in this example:
def sum_two() -> def sum_two(a: int, b: int) -> int
def sum_two(a: int) -> def sum_two(b: int) -> int
def sum_two(a: int, b: int) -> def sum_two() -> int
Implementation can be:
from returns.curry import partial
curry = lambda f: partial(partial, f)
@curry
def test(arg: int, other: str) -> str:
return str(arg) + other
print(test(1)("a")) # => 1a
print(test(2, "3")()) # => 23
print(test()(0, "c")) # => 0c
That's the typing part that is hard.
On the side note, it does not work like in Haskell, where a b c -> x
can be applied as a -> b -> c -> x
>>> from returns.curry import partial
>>>
>>> curry = lambda f: partial(partial, f)
>>>
>>> @curry
... def test(arg: int, other: str, last: str) -> str:
... return str(arg) + other + last
...
>>> test(1)('a')('v')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() missing 1 required positional argument: 'last'
>>> test(1)('a', 'v')
'1av'