mirror of
https://github.com/correl/typesafe-monads.git
synced 2024-11-24 11:09:58 +00:00
Ensure all monoids and monoids implement their appropriate operators
This commit is contained in:
parent
50a26a7b7a
commit
16c87c4d04
8 changed files with 53 additions and 0 deletions
|
@ -8,3 +8,5 @@ S = TypeVar("S")
|
|||
class Functor(Generic[T]):
|
||||
def map(self, function: Callable[[T], S]) -> Functor[S]: # pragma: no cover
|
||||
raise NotImplementedError
|
||||
|
||||
__mul__ = __rmul__ = map
|
||||
|
|
|
@ -34,3 +34,5 @@ class List(Monad[T], Monoidal[list]):
|
|||
return List(self.value + other.value)
|
||||
|
||||
__add__ = mappend
|
||||
__mul__ = __rmul__ = map
|
||||
__rshift__ = bind
|
||||
|
|
|
@ -15,3 +15,5 @@ class Monad(Applicative[T]):
|
|||
# https://github.com/python/mypy/issues/1317
|
||||
def bind(self, function: Callable[[T], Any]) -> Monad[S]: # pragma: no cover
|
||||
raise NotImplementedError
|
||||
|
||||
__rshift__ = bind
|
||||
|
|
|
@ -43,6 +43,9 @@ class Reader(Monad[T], Generic[Env, T]):
|
|||
name = self.function.__name__
|
||||
return f"<Reader {module}.{name}>"
|
||||
|
||||
__mul__ = __rmul__ = map
|
||||
__rshift__ = bind
|
||||
|
||||
|
||||
class Curried(Reader[Env, T]):
|
||||
def __call__(self, *args):
|
||||
|
|
|
@ -19,3 +19,15 @@ def test_associativity(monad) -> None:
|
|||
g: Callable[[int], str] = lambda x: str(x)
|
||||
m: Functor = monad.pure(3)
|
||||
assert m.map(lambda x: g(f(x))) == m.map(f).map(g)
|
||||
|
||||
|
||||
def test_map_mul_operator(monad) -> None:
|
||||
m: Functor = monad.pure(3)
|
||||
identity: Callable[[T], T] = lambda x: x
|
||||
assert m.map(identity) == m * identity
|
||||
|
||||
|
||||
def test_map_rmul_operator(monad) -> None:
|
||||
m: Functor = monad.pure(3)
|
||||
identity: Callable[[T], T] = lambda x: x
|
||||
assert m.map(identity) == identity * m
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import Callable
|
||||
|
||||
import pytest # type: ignore
|
||||
|
||||
from monads import Monad
|
||||
|
@ -9,6 +11,12 @@ def test_bind(monad) -> None:
|
|||
assert expected == monad.pure(1).bind(lambda x: monad.pure(x + 1))
|
||||
|
||||
|
||||
def test_bind_rshift_operator(monad) -> None:
|
||||
m: Monad[int] = monad.pure(2)
|
||||
f: Callable[[int], Monad[int]] = lambda x: monad.pure(x + 1)
|
||||
assert m.bind(f) == m >> f
|
||||
|
||||
|
||||
def test_left_identity(monad) -> None:
|
||||
n: int = 3
|
||||
|
||||
|
|
|
@ -28,6 +28,12 @@ def construct(constructor: Constructor, value: Any) -> Monoid:
|
|||
return cls(builder(value))
|
||||
|
||||
|
||||
def test_mappend_add_operator(constructor: Constructor) -> None:
|
||||
a: Monoid = construct(constructor, 1)
|
||||
b: Monoid = construct(constructor, 2)
|
||||
assert a.mappend(b) == a + b
|
||||
|
||||
|
||||
def test_associative(constructor: Constructor) -> None:
|
||||
a: Monoid = construct(constructor, 1)
|
||||
b: Monoid = construct(constructor, 2)
|
||||
|
|
|
@ -21,6 +21,18 @@ def test_functor_associativity() -> None:
|
|||
assert m.map(lambda x: g(f(x)))(0) == m.map(f).map(g)(0)
|
||||
|
||||
|
||||
def test_functor_map_mul_operator() -> None:
|
||||
m: Reader = Reader.pure(3)
|
||||
identity: Callable[[T], T] = lambda x: x
|
||||
assert m.map(identity)(0) == (m * identity)(0)
|
||||
|
||||
|
||||
def test_functor_map_rmul_operator() -> None:
|
||||
m: Reader = Reader.pure(3)
|
||||
identity: Callable[[T], T] = lambda x: x
|
||||
assert m.map(identity)(0) == (identity * m)(0)
|
||||
|
||||
|
||||
def test_applicative_fmap_using_ap() -> None:
|
||||
f: Callable[[int], int] = lambda x: x + 1
|
||||
m: Reader[int, int] = Reader.pure(3)
|
||||
|
@ -33,6 +45,12 @@ def test_monad_bind() -> None:
|
|||
assert expected(0) == m.bind(lambda x: Reader.pure(x + 1))(0)
|
||||
|
||||
|
||||
def test_monad_bind_rshift_operator() -> None:
|
||||
m: Reader[int, int] = Reader.pure(2)
|
||||
f: Callable[[int], Reader[int, int]] = lambda x: Reader.pure(x + 1)
|
||||
assert m.bind(f)(0) == (m >> f)(0)
|
||||
|
||||
|
||||
def test_monad_left_identity() -> None:
|
||||
n: int = 3
|
||||
|
||||
|
|
Loading…
Reference in a new issue