base-4.9.1.0: Basic libraries

Copyright | (c) The University of Glasgow 2001
License | BSD-style (see the file libraries/base/LICENSE)
Maintainer | libraries@haskell.org
Stability | experimental
Portability | portable
Safe Haskell | Trustworthy
Language | Haskell2010

Data.Either

Description

The Either type, and associated operations.

Synopsis

- data Either a b
  - = Left a
  - | Right b
- either :: (a -> c) -> (b -> c) -> Either a b -> c
- lefts :: [Either a b] -> [a]
- rights :: [Either a b] -> [b]
- isLeft :: Either a b -> Bool
- isRight :: Either a b -> Bool
- partitionEithers :: [Either a b] -> ([a], [b])

# Documentation

data Either a b Source #

The `Either` type represents values with two possibilities: 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").

#### Examples

The type ``Either` `String` `Int`` is the type of values which can be either a `String` or an `Int`. The `Left` constructor can be used only on `String`s, and the `Right` constructor can be used only on `Int`s:

    >>> let s = Left "foo" :: Either String Int
    >>> s
    Left "foo"
    >>> let n = Right 3 :: Either String Int
    >>> n
    Right 3
    >>> :type s
    s :: Either String Int
    >>> :type n
    n :: Either String Int

The `fmap` from our `Functor` instance will ignore `Left` values, but will apply the supplied function to values contained in a `Right`:

    >>> let s = Left "foo" :: Either String Int
    >>> let n = Right 3 :: Either String Int
    >>> fmap (*2) s
    Left "foo"
    >>> fmap (*2) n
    Right 6

The `Monad` instance for `Either` allows us to chain together multiple actions which may fail, and fail overall if any of the individual steps failed. First we'll write a function that can either parse an `Int` from a `Char`, or fail.

    >>> import Data.Char ( digitToInt, isDigit )
    >>> :{
        let parseEither :: Char -> Either String Int
            parseEither c
              | isDigit c = Right (digitToInt c)
              | otherwise = Left "parse error"
    >>> :}

The following should work, since both `'1'` and `'2'` can be parsed as `Int`s.

    >>> :{
        let parseMultiple :: Either String Int
            parseMultiple = do
              x <- parseEither '1'
              y <- parseEither '2'
              return (x + y)
    >>> :}

    >>> parseMultiple
    Right 3

But the following should fail overall, since the first operation where we attempt to parse `'m'` as an `Int` will fail:

    >>> :{
        let parseMultiple :: Either String Int
            parseMultiple = do
              x <- parseEither 'm'
              y <- parseEither '2'
              return (x + y)
    >>> :}

    >>> parseMultiple
    Left "parse error"

Constructors

Left a |
Right b |

Instances

Bifunctor Either # |
Methods bimap :: (a -> b) -> (c -> d) -> Either a c -> Either b d Source # first :: (a -> b) -> Either a c -> Either b c Source # second :: (b -> c) -> Either a b -> Either a c Source #
Show2 Either # |
Methods liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int -> Either a b -> ShowS Source # liftShowList2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> [Either a b] -> ShowS Source #
Read2 Either # |
Methods liftReadsPrec2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> Int -> ReadS (Either a b) Source # liftReadList2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> ReadS [Either a b] Source #
Ord2 Either # |
Methods liftCompare2 :: (a -> b -> Ordering) -> (c -> d -> Ordering) -> Either a c -> Either b d -> Ordering Source #
Eq2 Either # |
Methods liftEq2 :: (a -> b -> Bool) -> (c -> d -> Bool) -> Either a c -> Either b d -> Bool Source #
Monad (Either e) # |
Methods (>>=) :: Either e a -> (a -> Either e b) -> Either e b Source # (>>) :: Either e a -> Either e b -> Either e b Source # return :: a -> Either e a Source # fail :: String -> Either e a Source #
Functor (Either a) # |
Methods fmap :: (a -> b) -> Either a a -> Either a b Source # (<$) :: a -> Either a b -> Either a a Source #
MonadFix (Either e) # |
Methods mfix :: (a -> Either e a) -> Either e a Source #
Applicative (Either e) # |
Methods pure :: a -> Either e a Source # (<*>) :: Either e (a -> b) -> Either e a -> Either e b Source # (*>) :: Either e a -> Either e b -> Either e b Source # (<*) :: Either e a -> Either e b -> Either e a Source #
Foldable (Either a) # |
Methods fold :: Monoid m => Either a m -> m Source # foldMap :: Monoid m => (a -> m) -> Either a a -> m Source # foldr :: (a -> b -> b) -> b -> Either a a -> b Source # foldr' :: (a -> b -> b) -> b -> Either a a -> b Source # foldl :: (b -> a -> b) -> b -> Either a a -> b Source # foldl' :: (b -> a -> b) -> b -> Either a a -> b Source # foldr1 :: (a -> a -> a) -> Either a a -> a Source # foldl1 :: (a -> a -> a) -> Either a a -> a Source # toList :: Either a a -> [a] Source # null :: Either a a -> Bool Source # length :: Either a a -> Int Source # elem :: Eq a => a -> Either a a -> Bool Source # maximum :: Ord a => Either a a -> a Source # minimum :: Ord a => Either a a -> a Source # sum :: Num a => Either a a -> a Source # product :: Num a => Either a a -> a Source #
Traversable (Either a) # |
Methods traverse :: Applicative f => (a -> f b) -> Either a a -> f (Either a b) Source # sequenceA :: Applicative f => Either a (f a) -> f (Either a a) Source # mapM :: Monad m => (a -> m b) -> Either a a -> m (Either a b) Source # sequence :: Monad m => Either a (m a) -> m (Either a a) Source #
Generic1 (Either a) # |
Associated Types type Rep1 (Either a :: * -> *) :: * -> * Source # Methods from1 :: Either a a -> Rep1 (Either a) a Source # to1 :: Rep1 (Either a) a -> Either a a Source #
Show a => Show1 (Either a) # |
Methods liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Either a a -> ShowS Source # liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Either a a] -> ShowS Source #
Read a => Read1 (Either a) # |
Methods liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (Either a a) Source # liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [Either a a] Source #
Ord a => Ord1 (Either a) # |
Methods liftCompare :: (a -> b -> Ordering) -> Either a a -> Either a b -> Ordering Source #
Eq a => Eq1 (Either a) # |
Methods liftEq :: (a -> b -> Bool) -> Either a a -> Either a b -> Bool Source #
(Eq b, Eq a) => Eq (Either a b) # |
Methods (==) :: Either a b -> Either a b -> Bool Source # (/=) :: Either a b -> Either a b -> Bool Source #
(Data a, Data b) => Data (Either a b) # |
Methods gfoldl :: (forall d c. Data d => c (d -> c) -> d -> c c) -> (forall g. g -> c g) -> Either a b -> c (Either a b) Source # gunfold :: (forall c r. Data c => c (c -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Either a b) Source # toConstr :: Either a b -> Constr Source # dataTypeOf :: Either a b -> DataType Source # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (Either a b)) Source # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Either a b)) Source # gmapT :: (forall c. Data c => c -> c) -> Either a b -> Either a b Source # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r Source # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r Source # gmapQ :: (forall d. Data d => d -> u) -> Either a b -> [u] Source # gmapQi :: Int -> (forall d. Data d => d -> u) -> Either a b -> u Source # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Source # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Source # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Source #
(Ord b, Ord a) => Ord (Either a b) # |
Methods compare :: Either a b -> Either a b -> Ordering Source # (<) :: Either a b -> Either a b -> Bool Source # (<=) :: Either a b -> Either a b -> Bool Source # (>) :: Either a b -> Either a b -> Bool Source # (>=) :: Either a b -> Either a b -> Bool Source # max :: Either a b -> Either a b -> Either a b Source # min :: Either a b -> Either a b -> Either a b Source #
(Read b, Read a) => Read (Either a b) # |
Methods readsPrec :: Int -> ReadS (Either a b) Source # readList :: ReadS [Either a b] Source # readPrec :: ReadPrec (Either a b) Source # readListPrec :: ReadPrec [Either a b] Source #
(Show b, Show a) => Show (Either a b) # |
Methods showsPrec :: Int -> Either a b -> ShowS Source # show :: Either a b -> String Source # showList :: [Either a b] -> ShowS Source #
Generic (Either a b) # |
Associated Types type Rep (Either a b) :: * -> * Source # Methods from :: Either a b -> Rep (Either a b) x Source # to :: Rep (Either a b) x -> Either a b Source #
Semigroup (Either a b) # |
Methods (<>) :: Either a b -> Either a b -> Either a b Source # sconcat :: NonEmpty (Either a b) -> Either a b Source # stimes :: Integral b => b -> Either a b -> Either a b Source #
type Rep1 (Either a) # |
type Rep1 (Either a) = D1 (MetaData "Either" "Data.Either" "base" False) ((:+:) (C1 (MetaCons "Left" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a))) (C1 (MetaCons "Right" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) Par1)))
type Rep (Either a b) # |
type Rep (Either a b) = D1 (MetaData "Either" "Data.Either" "base" False) ((:+:) (C1 (MetaCons "Left" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a))) (C1 (MetaCons "Right" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 b))))
type (==) (Either k k1) a b # |
type (==) (Either k k1) a b

either :: (a -> c) -> (b -> c) -> Either a b -> c Source #

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`.

#### Examples

We create two values of type ``Either` `String` `Int``, one using the `Left` constructor and another using the `Right` constructor. Then we apply "either" the `length` function (if we have a `String`) or the "times-two" function (if we have an `Int`):

    >>> let s = Left "foo" :: Either String Int
    >>> let n = Right 3 :: Either String Int
    >>> either length (*2) s
    3
    >>> either length (*2) n
    6

lefts :: [Either a b] -> [a] Source #

Extracts from a list of `Either` all the `Left` elements. All the `Left` elements are extracted in order.

#### Examples

Basic usage:

    >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
    >>> lefts list
    ["foo","bar","baz"]

rights :: [Either a b] -> [b] Source #

Extracts from a list of `Either` all the `Right` elements. All the `Right` elements are extracted in order.

#### Examples

Basic usage:

    >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
    >>> rights list
    [3,7]

isLeft :: Either a b -> Bool Source #

Return `True` if the given value is a `Left`-value, `False` otherwise.

#### Examples

Basic usage:

    >>> isLeft (Left "foo")
    True
    >>> isLeft (Right 3)
    False

Assuming a `Left` value signifies some sort of error, we can use `isLeft` to write a very simple error-reporting function that does absolutely nothing in the case of success, and outputs "ERROR" if any error occurred.

This example shows how `isLeft` might be used to avoid pattern matching when one does not care about the value contained in the constructor:

    >>> import Control.Monad ( when )
    >>> let report e = when (isLeft e) $ putStrLn "ERROR"
    >>> report (Right 1)
    >>> report (Left "parse error")
    ERROR

Since: 4.7.0.0

isRight :: Either a b -> Bool Source #

Return `True` if the given value is a `Right`-value, `False` otherwise.

#### Examples

Basic usage:

    >>> isRight (Left "foo")
    False
    >>> isRight (Right 3)
    True

Assuming a `Left` value signifies some sort of error, we can use `isRight` to write a very simple reporting function that only outputs "SUCCESS" when a computation has succeeded.

This example shows how `isRight` might be used to avoid pattern matching when one does not care about the value contained in the constructor:

    >>> import Control.Monad ( when )
    >>> let report e = when (isRight e) $ putStrLn "SUCCESS"
    >>> report (Left "parse error")
    >>> report (Right 1)
    SUCCESS

Since: 4.7.0.0

partitionEithers :: [Either a b] -> ([a], [b]) Source #

Partitions a list of `Either` into two lists. All the `Left` elements are extracted, in order, to the first component of the output. Similarly the `Right` elements are extracted to the second component of the output.

#### Examples

Basic usage:

    >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
    >>> partitionEithers list
    (["foo","bar","baz"],[3,7])

The pair returned by ``partitionEithers` x` should be the same pair as `(`lefts` x, `rights` x)`:

    >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
    >>> partitionEithers list == (lefts list, rights list)
    True