mirror of
https://github.com/correl/typesafe-monads.git
synced 2024-11-21 19:18:42 +00:00
Add Monad.sequence
This commit is contained in:
parent
83b13a3e74
commit
77bf6b4735
2 changed files with 21 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
from typing import Any, Callable, Generic, TypeVar
|
||||
import functools
|
||||
from typing import Any, Callable, Generic, Iterable, List, TypeVar
|
||||
|
||||
from .applicative import Applicative
|
||||
from .functor import Functor
|
||||
|
@ -16,4 +17,17 @@ class Monad(Applicative[T]):
|
|||
def bind(self, function: Callable[[T], Any]) -> Monad[S]: # pragma: no cover
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def pure(cls, value: T) -> Monad[T]:
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def sequence(cls, xs: Iterable[Monad[T]]) -> Monad[List[T]]:
|
||||
"""Evaluate monadic actions in sequence, collecting results."""
|
||||
|
||||
def reducer(acc: Monad[List[T]], x: Monad[T]) -> Monad[List[T]]:
|
||||
return acc.bind(lambda acc_: x.map(lambda x_: acc_ + [x_]))
|
||||
|
||||
return functools.reduce(reducer, xs, cls.pure([]))
|
||||
|
||||
__rshift__ = bind
|
||||
|
|
|
@ -41,3 +41,9 @@ def test_associativity(monad) -> None:
|
|||
return monad.pure(n + 5)
|
||||
|
||||
assert m.bind(f).bind(g) == m.bind(lambda x: f(x).bind(g))
|
||||
|
||||
|
||||
def test_sequence(monad) -> None:
|
||||
assert monad.pure([1, 2, 3]) == monad.sequence(
|
||||
[monad.pure(1), monad.pure(2), monad.pure(3)]
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue