typesafe-monads/tests/test_monoids.py

57 lines
1.5 KiB
Python

import pytest # type: ignore
from typing import Any, Callable, Tuple, Type
from monads.list import List
from monads.monoid import Monoid, String, Addition, Multiplication
from monads.maybe import First, Last, Just
Constructor = Tuple[Type, Callable[[Any], Any]]
@pytest.fixture(
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]),
],
)
def constructor(request) -> Constructor:
return request.param
def construct(constructor: Constructor, value: Any) -> Monoid:
cls, builder = constructor
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)
c: Monoid = construct(constructor, 3)
assert (a + b) + c == a + (b + c)
def test_mconcat_empty(constructor: Constructor) -> None:
cls, _ = constructor
zero: Monoid = cls.mzero()
assert zero == cls.mconcat([])
def test_mconcat(constructor: Constructor) -> None:
cls, _ = constructor
a: Monoid = construct(constructor, 1)
b: Monoid = construct(constructor, 2)
c: Monoid = construct(constructor, 3)
expected: Monoid = a.mappend(b).mappend(c)
assert expected == cls.mconcat([a, b, c])