2018-10-12 00:44:57 +00:00
|
|
|
import pytest # type: ignore
|
2018-10-13 06:27:39 +00:00
|
|
|
from typing import Any, Callable, Tuple, Type
|
2018-10-12 21:02:17 +00:00
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
from monads.list import List
|
|
|
|
from monads.monoid import Monoid, String, Addition, Multiplication
|
2018-10-12 00:44:57 +00:00
|
|
|
from monads.maybe import First, Last, Just
|
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
Constructor = Tuple[Type, Callable[[Any], Any]]
|
2018-10-12 00:44:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(
|
2018-10-13 06:27:39 +00:00
|
|
|
scope="module",
|
|
|
|
params=[
|
|
|
|
(First, lambda x: Just(x)),
|
|
|
|
(Last, lambda x: Just(x)),
|
|
|
|
(String, lambda x: str(x)),
|
|
|
|
(Addition, lambda x: x),
|
|
|
|
(Multiplication, lambda x: x),
|
|
|
|
(List, lambda x: [x]),
|
|
|
|
],
|
2018-10-12 00:44:57 +00:00
|
|
|
)
|
2018-10-13 06:27:39 +00:00
|
|
|
def constructor(request) -> Constructor:
|
2018-10-12 00:44:57 +00:00
|
|
|
return request.param
|
|
|
|
|
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
def construct(constructor: Constructor, value: Any) -> Monoid:
|
|
|
|
cls, builder = constructor
|
|
|
|
return cls(builder(value))
|
|
|
|
|
|
|
|
|
2018-12-06 18:53:07 +00:00
|
|
|
def test_mappend_add_operator(constructor: Constructor) -> None:
|
|
|
|
a: Monoid = construct(constructor, 1)
|
|
|
|
b: Monoid = construct(constructor, 2)
|
|
|
|
assert a.mappend(b) == a + b
|
|
|
|
|
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
def test_associative(constructor: Constructor) -> None:
|
|
|
|
a: Monoid = construct(constructor, 1)
|
|
|
|
b: Monoid = construct(constructor, 2)
|
|
|
|
c: Monoid = construct(constructor, 3)
|
2018-10-12 00:44:57 +00:00
|
|
|
|
|
|
|
assert (a + b) + c == a + (b + c)
|
|
|
|
|
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
def test_mconcat_empty(constructor: Constructor) -> None:
|
|
|
|
cls, _ = constructor
|
2018-10-12 00:44:57 +00:00
|
|
|
zero: Monoid = cls.mzero()
|
|
|
|
assert zero == cls.mconcat([])
|
|
|
|
|
2018-10-13 06:27:39 +00:00
|
|
|
|
|
|
|
def test_mconcat(constructor: Constructor) -> None:
|
|
|
|
cls, _ = constructor
|
|
|
|
a: Monoid = construct(constructor, 1)
|
|
|
|
b: Monoid = construct(constructor, 2)
|
|
|
|
c: Monoid = construct(constructor, 3)
|
2018-10-12 00:44:57 +00:00
|
|
|
expected: Monoid = a.mappend(b).mappend(c)
|
|
|
|
assert expected == cls.mconcat([a, b, c])
|