correl / typesafe-monads

https://pypi.org/project/typesafe-monads/
MIT License
23 stars 5 forks source link

map and apply does not work with curried function #2

Open crypticmind opened 5 years ago

crypticmind commented 5 years ago

I really like the idea of typesafe monads in Python (what a time to be alive 😄)

However, I tried this and it doesn't work:

from monads.currying import curry
from monads.result import Result, Ok, Err

@curry
def add(x: int, y: int) -> int:
    return x + y

def test_map_apply_result():
    xx: Result[int, Exception] = Ok(2)
    yy: Result[int, Exception] = Ok(3)
    assert add * xx & yy == Ok(5)

The problem seems to be that add * xx calls map from Reader instead of Result, and ends up returning a <Reader monads.reader.<lambda>(x)>

anentropic commented 4 years ago

somehow the problem is in the @curry

redefining add as add = lambda x: lambda y: y + x (like the subtract example on the README) seems to work fine

anentropic commented 4 years ago

returning Reader seems to be inherent in the implementation of @curry https://github.com/correl/typesafe-monads/blob/master/monads/currying.py#L16 PyMonad does the same, I guess that is correct

so add is a Reader and the xx,yy are Results

another way that works, with the @curry'd add function, is:

In [9]: (xx * add) & yy
Out[9]: <Ok 5>

the monad classes here define __mul__ = __rmul__ = map

so I guess the problem is in the precedence of __mul__ vs __rmul__ as described here: https://stackoverflow.com/a/5182501/202168

(or maybe PyMonad is wrong and there's no reason for @curry to return a Reader?)