Source code for returns.interfaces.altable

from abc import abstractmethod
from typing import Callable, ClassVar, Generic, NoReturn, Sequence, TypeVar

from typing_extensions import final

from returns.functions import compose, identity
from returns.primitives.asserts import assert_equal
from import KindN
from returns.primitives.laws import (

_FirstType = TypeVar('_FirstType')
_SecondType = TypeVar('_SecondType')
_ThirdType = TypeVar('_ThirdType')
_UpdatedType = TypeVar('_UpdatedType')

_AltableType = TypeVar('_AltableType', bound='AltableN')

# Used in laws:
_NewType1 = TypeVar('_NewType1')
_NewType2 = TypeVar('_NewType2')

[docs]@final class _LawSpec(LawSpecDef): """ Mappable or functor laws. """
[docs] @law_definition def identity_law( altable: 'AltableN[_FirstType, _SecondType, _ThirdType]', ) -> None: """Mapping identity over a value must return the value unchanged.""" assert_equal(altable.alt(identity), altable)
[docs] @law_definition 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)), )
[docs]class AltableN( Generic[_FirstType, _SecondType, _ThirdType], Lawful['AltableN[_FirstType, _SecondType, _ThirdType]'], ): """Modifies the second type argument with a pure function.""" _laws: ClassVar[Sequence[Law]] = ( Law1(_LawSpec.identity_law), Law3(_LawSpec.associative_law), )
[docs] @abstractmethod def alt( self: _AltableType, function: Callable[[_SecondType], _UpdatedType], ) -> KindN[_AltableType, _FirstType, _UpdatedType, _ThirdType]: """Allows to run a pure function over a container."""
#: Type alias for kinds with two type arguments. Altable2 = AltableN[_FirstType, _SecondType, NoReturn] #: Type alias for kinds with three type arguments. Altable3 = AltableN[_FirstType, _SecondType, _ThirdType]