Data.Either.Combinators

either-5.0.2: Combinators for working with sums

Copyright | (c) 2010-2014 Gregory Crosswhite Chris Done Edward Kmett
License | BSD-style
Maintainer | ekmett@gmail.com
Stability | provisional
Portability | portable
Safe Haskell | Safe-Inferred
Language | Haskell2010

Data.Either.Combinators

Description

Functions for probing and unwrapping values inside of `Either`.

Most of these combinators are provided for pedagogical purposes and exist in more general forms in other libraries. To that end alternative definitions are supplied below.

Synopsis

- isLeft :: Either a b -> Bool
- isRight :: Either a b -> Bool
- fromLeft :: a -> Either a b -> a
- fromRight :: b -> Either a b -> b
- fromLeft' :: Either a b -> a
- fromRight' :: Either a b -> b
- mapBoth :: (a -> c) -> (b -> d) -> Either a b -> Either c d
- mapLeft :: (a -> c) -> Either a b -> Either c b
- mapRight :: (b -> c) -> Either a b -> Either a c
- whenLeft :: Applicative m => Either a b -> (a -> m ()) -> m ()
- whenRight :: Applicative m => Either a b -> (b -> m ()) -> m ()
- unlessLeft :: Applicative m => Either a b -> (b -> m ()) -> m ()
- unlessRight :: Applicative m => Either a b -> (a -> m ()) -> m ()
- leftToMaybe :: Either a b -> Maybe a
- rightToMaybe :: Either a b -> Maybe b
- maybeToLeft :: b -> Maybe a -> Either a b
- maybeToRight :: b -> Maybe a -> Either b a
- eitherToError :: MonadError e m => Either e a -> m a
- swapEither :: Either e a -> Either a e

# Documentation

isLeft :: Either a b -> Bool #

The `isLeft` function returns `True` iff its argument is of the form ``Left` _`.

Using `Control.Lens`:

    isLeft ≡ has _Left

    >>> isLeft (Left 12)
    True

    >>> isLeft (Right 12)
    False

isRight :: Either a b -> Bool #

The `isRight` function returns `True` iff its argument is of the form ``Right` _`.

Using `Control.Lens`:

    isRight ≡ has _Right

    >>> isRight (Left 12)
    False

    >>> isRight (Right 12)
    True

fromLeft :: a -> Either a b -> a #

Extract the left value or a default.

    fromLeft b ≡ either id (const b)

    >>> fromLeft "hello" (Right 42)
    "hello"

    >>> fromLeft "hello" (Left "world")
    "world"

fromRight :: b -> Either a b -> b #

Extract the right value or a default.

    fromRight b ≡ either (const b) id

    >>> fromRight "hello" (Right "world")
    "world"

    >>> fromRight "hello" (Left 42)
    "hello"

fromLeft' :: Either a b -> a #

Extracts the element out of a `Left` and throws an error if its argument take the form ``Right` _`.

Using `Control.Lens`:

    fromLeft' x ≡ x^?!_Left

    >>> fromLeft' (Left 12)
    12

fromRight' :: Either a b -> b #

Extracts the element out of a `Right` and throws an error if its argument take the form ``Left` _`.

Using `Control.Lens`:

    fromRight' x ≡ x^?!_Right

    >>> fromRight' (Right 12)
    12

mapBoth :: (a -> c) -> (b -> d) -> Either a b -> Either c d #

The `mapBoth` function takes two functions and applies the first if iff the value takes the form ``Left` _` and the second if the value takes the form ``Right` _`.

Using `Data.Bifunctor`:

    mapBoth = bimap

Using `Control.Arrow`:

    mapBoth = (+++)

    >>> mapBoth (*2) (*3) (Left 4)
    Left 8

    >>> mapBoth (*2) (*3) (Right 4)
    Right 12

mapLeft :: (a -> c) -> Either a b -> Either c b #

The `mapLeft` function takes a function and applies it to an Either value iff the value takes the form ``Left` _`.

Using `Data.Bifunctor`:

    mapLeft = first

Using `Control.Arrow`:

    mapLeft = (left)

Using `Control.Lens`:

    mapLeft = over _Left

    >>> mapLeft (*2) (Left 4)
    Left 8

    >>> mapLeft (*2) (Right "hello")
    Right "hello"

mapRight :: (b -> c) -> Either a b -> Either a c #

The `mapRight` function takes a function and applies it to an Either value iff the value takes the form ``Right` _`.

Using `Data.Bifunctor`:

    mapRight = second

Using `Control.Arrow`:

    mapRight = (right)

Using `Control.Lens`:

    mapRight = over _Right

    >>> mapRight (*2) (Left "hello")
    Left "hello"

    >>> mapRight (*2) (Right 4)
    Right 8

whenLeft :: Applicative m => Either a b -> (a -> m ()) -> m () #

The `whenLeft` function takes an `Either` value and a function which returns a monad. The monad is only executed when the given argument takes the form ``Left` _`, otherwise it does nothing.

Using `Control.Lens`:

    whenLeft ≡ forOf_ _Left

    >>> whenLeft (Left 12) print
    12

whenRight :: Applicative m => Either a b -> (b -> m ()) -> m () #

The `whenRight` function takes an `Either` value and a function which returns a monad. The monad is only executed when the given argument takes the form ``Right` _`, otherwise it does nothing.

Using `Data.Foldable`:

    whenRight ≡ forM_

Using `Control.Lens`:

    whenRight ≡ forOf_ _Right

    >>> whenRight (Right 12) print
    12

unlessLeft :: Applicative m => Either a b -> (b -> m ()) -> m () #

A synonym of `whenRight`.

unlessRight :: Applicative m => Either a b -> (a -> m ()) -> m () #

A synonym of `whenLeft`.

leftToMaybe :: Either a b -> Maybe a #

Maybe get the `Left` side of an `Either`.

    leftToMaybe ≡ either Just (const Nothing)

Using `Control.Lens`:

    leftToMaybe ≡ preview _Left
    leftToMaybe x ≡ x^?_Left

    >>> leftToMaybe (Left 12)
    Just 12

    >>> leftToMaybe (Right 12)
    Nothing

rightToMaybe :: Either a b -> Maybe b #

Maybe get the `Right` side of an `Either`.

    rightToMaybe ≡ either (const Nothing) Just

Using `Control.Lens`:

    rightToMaybe ≡ preview _Right
    rightToMaybe x ≡ x^?_Right

    >>> rightToMaybe (Left 12)
    Nothing

    >>> rightToMaybe (Right 12)
    Just 12

maybeToLeft :: b -> Maybe a -> Either a b #

Maybe produce a `Left`, otherwise produce a `Right`.

    >>> maybeToLeft "default" (Just 12)
    Left 12

    >>> maybeToLeft "default" Nothing
    Right "default"

maybeToRight :: b -> Maybe a -> Either b a #

Maybe produce a `Right`, otherwise produce a `Left`.

    >>> maybeToRight "default" (Just 12)
    Right 12

    >>> maybeToRight "default" Nothing
    Left "default"

eitherToError :: MonadError e m => Either e a -> m a #

Generalize `Either e` as `MonadError e m`.

If the argument has form `Left e`, an error is produced in the monad via `throwError`. Otherwise, the `Right a` part is forwarded.

swapEither :: Either e a -> Either a e #

Swap the `Left` and `Right` sides of an `Either`.

    >>> swapEither (Right 3)
    Left 3

    >>> swapEither (Left "error")
    Right "error"