Source code for haskpy.types.either

"""Values with two possibilities

.. autosummary::
   :toctree:

   Either
   Left
   Right
   either
   is_left
   is_right
   from_left
   from_right
   left
   right

"""

import attr
import hypothesis.strategies as st

from haskpy.typeclasses import Monad, Eq
from haskpy.internal import class_function, immutable

from haskpy.optics import prism

from haskpy.testing import eq_test
from haskpy import testing
from haskpy.types.function import function


[docs]@immutable class Either(Monad, Eq): match = attr.ib()
[docs] @class_function def pure(cls, x): return Right(x)
[docs] def map(self, f): return self.match( Left=lambda _: self, Right=lambda x: Right(f(x)), )
[docs] def apply_to(self, x): return self.match( Left=lambda _: self, Right=lambda f: x.map(f), )
[docs] def bind(self, f): return self.match( Left=lambda _: self, Right=lambda x: f(x), )
[docs] def __eq__(self, other): return self.match( Left=lambda x: other.match( Left=lambda y: x == y, Right=lambda _: False, ), Right=lambda x: other.match( Left=lambda _: False, Right=lambda y: x == y, ), )
[docs] def __eq_test__(self, other, data): return self.match( Left=lambda x: other.match( Left=lambda y: eq_test(x, y, data=data), Right=lambda _: False, ), Right=lambda x: other.match( Left=lambda _: False, Right=lambda y: eq_test(x, y, data=data), ), )
def __repr__(self): return self.match( Left=lambda x: "Left({0})".format(repr(x)), Right=lambda x: "Right({0})".format(repr(x)), ) @class_function def sample_value(cls, a, b): return st.one_of(a.map(Left), b.map(Right)) sample_type = testing.sample_type_from_value( testing.sample_type(), testing.sample_type(), ) sample_functor_type = testing.sample_type_from_value( testing.sample_type(), ) sample_applicative_type = sample_functor_type sample_monad_type = sample_functor_type sample_eq_type = testing.sample_type_from_value( testing.sample_eq_type(), testing.sample_eq_type(), )
[docs]def Left(x): return Either(lambda *, Left, Right: Left(x))
[docs]@function def either(f, g, e): """(a -> c) -> (b -> c) -> Either a b -> c""" return e.match(Left=f, Right=g)
[docs]@function def is_left(m): return m.match( Left=lambda _: True, Right=lambda _: False, )
[docs]@function def is_right(m): return m.match( Left=lambda _: False, Right=lambda _: True, )
[docs]@function def from_left(x, e): return e.match( Left=lambda y: y, Right=lambda _: x, )
[docs]@function def from_right(x, e): return e.match( Left=lambda _: x, Right=lambda y: y, )
# # Optics # left = prism( lambda m: m.match( Left=lambda x: Right(x), Right=lambda _: Left(m), ), lambda x: Left(x), ) right = prism( lambda m: m.match( Left=lambda _: Left(m), Right=lambda x: Right(x), ), lambda x: Right(x), )