Ejemplo n.º 1
0
class DiverseFailableN(
    FailableN[_FirstType, _SecondType, _ThirdType],
    BiMappableN[_FirstType, _SecondType, _ThirdType],
    Lawful['DiverseFailableN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Base type for types that have any failed value.

    Like ``Result`` types.
    """

    _laws: ClassVar[Sequence[Law]] = (
        Law3(_DiverseFailableLawSpec.map_short_circuit_law),
        Law3(_DiverseFailableLawSpec.bind_short_circuit_law),
        Law3(_DiverseFailableLawSpec.apply_short_circuit_law),
        Law3(_DiverseFailableLawSpec.alt_short_circuit_law),
    )

    @classmethod
    @abstractmethod
    def from_failure(
        cls: Type[_DiverseFailableType],
        inner_value: _UpdatedType,
    ) -> KindN[_DiverseFailableType, _FirstType, _UpdatedType, _ThirdType]:
        """Unit method to create new containers from any raw value."""
Ejemplo n.º 2
0
class MaybeLikeN(
        failable.SingleFailableN[_FirstType, _SecondType, _ThirdType],
        Lawful['MaybeLikeN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Type for values that do look like a ``Maybe``.

    For example, ``RequiresContextMaybe`` should be created from this interface.
    Cannot be unwrapped or compared.
    """

    _laws: ClassVar[Sequence[Law]] = (
        Law2(_LawSpec.map_short_circuit_law),
        Law2(_LawSpec.bind_short_circuit_law),
        Law2(_LawSpec.bind_optional_short_circuit_law),
        Law3(_LawSpec.lash_short_circuit_law),
        Law2(_LawSpec.unit_structure_law),
    )

    @abstractmethod
    def bind_optional(
        self: _MaybeLikeType,
        function: Callable[[_FirstType], Optional[_UpdatedType]],
    ) -> KindN[_MaybeLikeType, _UpdatedType, _SecondType, _ThirdType]:
        """Binds a function that returns ``Optional`` values."""

    @classmethod
    @abstractmethod
    def from_optional(
        cls: Type[_MaybeLikeType],  # noqa: N805
        inner_value: Optional[_ValueType],
    ) -> KindN[_MaybeLikeType, _ValueType, _SecondType, _ThirdType]:
        """Unit method to create containers from ``Optional`` value."""
Ejemplo n.º 3
0
class MappableN(
    Generic[_FirstType, _SecondType, _ThirdType],
    Lawful['MappableN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Allows to chain wrapped values in containers with regular functions.

    Behaves like a functor.

    See also:
        - https://en.wikipedia.org/wiki/Functor

    """

    _laws: ClassVar[Sequence[Law]] = (
        Law1(_LawSpec.identity_law),
        Law3(_LawSpec.associative_law),
    )

    @abstractmethod  # noqa: WPS125
    def map(  # noqa: WPS125
        self: _MappableType,
        function: Callable[[_FirstType], _UpdatedType],
    ) -> KindN[_MappableType, _UpdatedType, _SecondType, _ThirdType]:
        """Allows to run a pure function over a container."""
Ejemplo n.º 4
0
class ResultLikeN(
    ContainerN[_FirstType, _SecondType, _ThirdType],
    bimappable.BiMappableN[_FirstType, _SecondType, _ThirdType],
    rescuable.RescuableN[_FirstType, _SecondType, _ThirdType],
    Lawful['ResultLikeN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Base types for types that looks like ``Result`` but cannot be unwrapped.

    Like ``RequiresContextResult`` or ``FutureResult``.
    """

    _laws: ClassVar[Sequence[Law]] = (
        Law3(_LawSpec.map_short_circuit_law),
        Law3(_LawSpec.bind_short_circuit_law),
        Law3(_LawSpec.alt_short_circuit_law),
        Law3(_LawSpec.rescue_short_circuit_law),
    )

    @abstractmethod
    def swap(
        self: _ResultLikeType,
    ) -> KindN[_ResultLikeType, _SecondType, _FirstType, _ThirdType]:
        """Swaps value and error types in ``Result``."""

    @abstractmethod
    def bind_result(
        self: _ResultLikeType,
        function: Callable[[_FirstType], 'Result[_UpdatedType, _SecondType]'],
    ) -> KindN[_ResultLikeType, _UpdatedType, _SecondType, _ThirdType]:
        """Runs ``Result`` returning function over a container."""

    @classmethod
    @abstractmethod
    def from_result(
        cls: Type[_ResultLikeType],  # noqa: N805
        inner_value: 'Result[_ValueType, _ErrorType]',
    ) -> KindN[_ResultLikeType, _ValueType, _ErrorType, _ThirdType]:
        """Unit method to create new containers from any raw value."""

    @classmethod
    @abstractmethod
    def from_failure(
        cls: Type[_ResultLikeType],  # noqa: N805
        inner_value: _ErrorType,
    ) -> KindN[_ResultLikeType, _FirstType, _ErrorType, _ThirdType]:
        """Unit method to create new containers from any raw value."""
Ejemplo n.º 5
0
class ContainerN(
    ApplicativeN[_FirstType, _SecondType, _ThirdType],
    bindable.BindableN[_FirstType, _SecondType, _ThirdType],
    Lawful['ContainerN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Handy alias for types with ``.bind``, ``.map``, and ``.apply`` methods.

    Should be a base class for almost any containers you write.

    See also:
        - https://bit.ly/2CTEVov

    """

    _laws: ClassVar[Sequence[Law]] = (
        Law3(_LawSpec.left_identity_law),
        Law1(_LawSpec.right_identity_law),
        Law3(_LawSpec.associative_law),
    )
Ejemplo n.º 6
0
class ApplicativeN(
    Generic[_FirstType, _SecondType, _ThirdType],
    Lawful['ApplicativeN'],
):
    """
    Allows to create unit containers from raw values and to apply wrapped funcs.

    See also:
        https://en.wikipedia.org/wiki/Applicative_functor
        http://learnyouahaskell.com/functors-applicative-functors-and-monoids

    """

    _laws: ClassVar[Sequence[Law]] = (
        Law1(_LawSpec.identity),
        Law3(_LawSpec.interchange),
        Law3(_LawSpec.homomorphism),
        Law3(_LawSpec.composition),
    )

    @abstractmethod
    def apply(
        self: _ApplicativeType,
        container: KindN[
            _ApplicativeType,
            Callable[[_FirstType], _UpdatedType],
            _SecondType,
            _ThirdType,
        ],
    ) -> KindN[_ApplicativeType, _UpdatedType, _SecondType, _ThirdType]:
        """Allows to apply a wrapped function over a container."""

    @classmethod
    @abstractmethod
    def from_value(
        cls: Type[_ApplicativeType],  # noqa: N805
        inner_value: _UpdatedType,
    ) -> KindN[_ApplicativeType, _UpdatedType, _SecondType, _ThirdType]:
        """Unit method to create new containers from any raw value."""
Ejemplo n.º 7
0
class FailableN(
        _container.ContainerN[_FirstType, _SecondType, _ThirdType],
        lashable.LashableN[_FirstType, _SecondType, _ThirdType],
        Lawful['FailableN[_FirstType, _SecondType, _ThirdType]'],
):
    """
    Base type for types that can fail.

    It is a raw type and should not be used directly.
    Use ``SingleFailableN`` and ``DiverseFailableN`` instead.
    """

    _laws: ClassVar[Sequence[Law]] = (Law3(
        _FailableLawSpec.lash_short_circuit_law), )
Ejemplo n.º 8
0
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),
    )

    @abstractmethod
    def alt(
        self: _AltableType,
        function: Callable[[_SecondType], _UpdatedType],
    ) -> KindN[_AltableType, _FirstType, _UpdatedType, _ThirdType]:
        """Allows to run a pure function over a container."""
Ejemplo n.º 9
0
class Equable(Lawful['Equable']):
    """
    Interface for types that can be compared with real values.

    Not all types can, because some don't have the value at a time:
    - ``Future`` has to be awaited to get the value
    - ``Reader`` has to be called to get the value

    """

    _laws: ClassVar[Sequence[Law]] = (
        Law1(_LawSpec.reflexive_law),
        Law2(_LawSpec.symmetry_law),
        Law3(_LawSpec.transitivity_law),
    )

    @abstractmethod
    def equals(self: _EqualType, other: _EqualType) -> bool:
        """Type-safe equality check for values of the same type."""
Ejemplo n.º 10
0
class PairLikeN(
    bindable.BindableN[_FirstType, _SecondType, _ThirdType],
    swappable.SwappableN[_FirstType, _SecondType, _ThirdType],
    lashable.LashableN[_FirstType, _SecondType, _ThirdType],
    equable.Equable,
):
    """Special interface for types that look like a ``Pair``."""

    _laws: ClassVar[Sequence[Law]] = (
        Law2(_LawSpec.pair_equality_law),
        Law3(_LawSpec.pair_left_identity_law),
    )

    @abstractmethod
    def pair(
        self: _PairLikeKind,
        function: Callable[
            [_FirstType, _SecondType],
            KindN[_PairLikeKind, _NewFirstType, _NewSecondType, _ThirdType],
        ],
    ) -> KindN[_PairLikeKind, _NewFirstType, _NewSecondType, _ThirdType]:
        """Allows to work with both arguments at the same time."""

    @classmethod
    @abstractmethod
    def from_paired(
        cls: Type[_PairLikeKind],
        first: _NewFirstType,
        second: _NewSecondType,
    ) -> KindN[_PairLikeKind, _NewFirstType, _NewSecondType, _ThirdType]:
        """Allows to create a PairLikeN from just two values."""

    @classmethod
    @abstractmethod
    def from_unpaired(
        cls: Type[_PairLikeKind],
        inner_value: _NewFirstType,
    ) -> KindN[_PairLikeKind, _NewFirstType, _NewFirstType, _ThirdType]:
        """Allows to create a PairLikeN from just a single object."""