def associativity_law( mappable: 'MappableN[_FirstType, _SecondType, _ThirdType]', first: Callable[[_FirstType], _NewType1], second: Callable[[_NewType1], _NewType2], ) -> None: """Mapping twice or mapping a composition is the same thing.""" assert_equal( mappable.map(first).map(second), mappable.map(compose(first, second)), )
def associative_law( altable: 'AltableN[_FirstType, _SecondType, _ThirdType]', first: Callable[[_SecondType], _NewType1], second: Callable[[_NewType1], _NewType2], ) -> None: """Mapping twice or mapping a composition is the same thing.""" assert_equal( altable.alt(first).alt(second), altable.alt(compose(first, second)), )
def composition_law( container: 'ApplicativeN[_FirstType, _SecondType, _ThirdType]', first: Callable[[_FirstType], _NewType1], second: Callable[[_NewType1], _NewType2], ) -> None: """ Composition law. Apply two functions twice is the same as applying their composition once. """ assert_equal( container.apply(container.from_value(compose(first, second))), container.apply(container.from_value(first), ).apply( container.from_value(second), ), )
def test_function_composition(): """Ensures that functions can be composed and return type is correct.""" second_after_first = compose(_first, _second) assert second_after_first(1) is True assert second_after_first(0) is True