예제 #1
0
def isLeft(x: Either(a, c)) -> bool:
    """
    isLeft :: Either a b -> bool

    Return True if the given value is a Left-value, False otherwise.
    """
    return ~(caseof(x) | m(Right(m.x)) >> False | m(Left(m.x)) >> True)
예제 #2
0
def either(fa: a >> c, fb: b >> c, e: Either(a, b)) -> c:
    """
    either :: (a -> c) -> (b -> c) -> Either a b -> c

    Case analysis for the Either type. If the value is Left(a), apply the first
    function to a; if it is Right(b), apply the second function to b.
    """
    return ~(caseof(e) | m(Left(m.a)) >> fa(p.a) | m(Right(m.b)) >> fb(p.b))
예제 #3
0
def null(xs):
    """
    null :: [a] -> bool

    Test whether the structure is empty.
    """
    return ~(caseof(xs)
                | m(m.y ^ m.ys) >> False
                | m(m.ys)       >> True)
예제 #4
0
def maybeToList(xs : Maybe(a)) -> [a]:
    """
    ``maybeToList :: Maybe a -> [a]``

    The maybeToList function returns an empty list when given ``Nothing`` or a
    singleton list when not given ``Nothing``.
    """
    return ~(caseof(xs)
                | m(Nothing)   >> L[[]]
                | m(Just(m.x)) >> L[[p.x]])
예제 #5
0
def foldr(f, z, xs):
    """
    foldr :: (a -> b -> b) -> b -> [a] -> b

    foldr, applied to a binary operator, a starting value (typically the
    right-identity of the operator), and a list, reduces the list using the
    binary operator, from right to left
    """
    return ~(caseof(xs)
                | m(L[[]])     >> z
                | m(m.a ^ m.b) >> f(p.a, foldr(f, z, p.b)))
예제 #6
0
    a value of type `Either a b` is either `Left a` or `Right b`.

    The Either type is sometimes used to represent a value which is
    either correct or an error; by convention, the `Left` constructor is used
    to hold an error value and the `Right` constructor is used
    to hold a correct value (mnemonic: “right” also means “correct”).
    """
    Left: a
    Right: b


Left, Right = Either.enums

instance(Functor,
         Either).where(fmap=lambda f, v: ~(caseof(v)
                                           | m(Left(m.e)) >> Left(p.e)
                                           | m(Right(m.ra)) >> Right(f(p.ra))))

instance(Applicative,
         Either).where(pure=Right,
                       ap=lambda v, x: ~(caseof(v)
                                         | m(Left(m.l)) >> Left(p.l)
                                         | m(Right(m.r)) >> fmap(p.r, x)))

instance(Monad, Either).where(bind=lambda v, f: ~(caseof(v)
                                                  | m(Left(m.e)) >> Left(p.e)
                                                  | m(Right(m.a)) >> f(p.a)))


def in_either(fn):
    """
예제 #7
0
def isNothing(a : Maybe(a)) -> bool:
    return ~(caseof(a)
                | m(Nothing)   >> True
                | m(Just(m.x)) >> False)
예제 #8
0
def listToMaybe(xs : [a]) -> Maybe(a):
    return ~(caseof(xs)
                | m(m.a ^ m.b) >> Just(p.a)
                | m(m.a)       >> Nothing)
예제 #9
0
    (represented as ``Just a``), or it is empty (represented as ``Nothing``).
    Using Maybe is a good way to deal with errors or exceptional cases
    without resorting to drastic measures such as error.

    The ``Maybe`` type is also a monad.
    It is a simple kind of error monad,
    where all errors are represented by ``Nothing``.
    A richer error monad can be built using the ``Either`` type.
    """
    Nothing : []
    Just : a
Nothing, Just = Maybe.enums

instance(Functor, Maybe).where(
    fmap = lambda f, x: ~(caseof(x)
                            | m(Just(m.a)) >> Just(f(p.a))
                            | m(Nothing)   >> Nothing)
)

instance(Applicative, Maybe).where(
    pure = Just,
    ap = lambda fs, xs: ~(caseof((fs, xs))
                            | m((Just(m.f), Just(m.x))) >> Just(p.f(p.x))
                            | m((Nothing, m.x)) >> Nothing)
)

instance(Monad, Maybe).where(
    bind = lambda x, f: ~(caseof(x)
                            | m(Just(m.a)) >> f(p.a)
                            | m(Nothing)   >> Nothing)
)