Copyright | (c) The University of Glasgow 2001 |
---|---|

License | BSD-style (see the file libraries/base/LICENSE) |

Maintainer | libraries@haskell.org |

Stability | stable |

Portability | portable |

Safe Haskell | Trustworthy |

Language | Haskell2010 |

The Either type, and associated operations.

# Documentation

The `Either`

type represents values with two possibilities: a value of
type

is either `Either`

a b

or `Left`

a

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

is the type of values which can be either
a `Either`

`String`

`Int`

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

`>>>`

Left "foo"`s`

`>>>`

`let n = Right 3 :: Either String Int`

`>>>`

Right 3`n`

`>>>`

s :: Either String Int`:type s`

`>>>`

n :: Either String Int`:type n`

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`

`>>>`

Left "foo"`fmap (*2) s`

`>>>`

Right 6`fmap (*2) n`

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)`:{`

`>>>`

`:}`

`>>>`

Right 3`parseMultiple`

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)`:{`

`>>>`

`:}`

`>>>`

Left "parse error"`parseMultiple`

#### Instances

Generic1 (Either a :: Type -> Type) Source # | |||||

Defined in GHC.Internal.Generics
| |||||

Applicative (Either e) Source # | @since base-3.0 | ||||

Defined in GHC.Internal.Data.Either | |||||

Functor (Either a) Source # | @since base-3.0 | ||||

Monad (Either e) Source # | @since base-4.4.0.0 | ||||

MonadFix (Either e) Source # | @since base-4.3.0.0 | ||||

Foldable (Either a) Source # | @since base-4.7.0.0 | ||||

Defined in GHC.Internal.Data.Foldable fold :: Monoid m => Either a m -> m Source # foldMap :: Monoid m => (a0 -> m) -> Either a a0 -> m Source # foldMap' :: Monoid m => (a0 -> m) -> Either a a0 -> m Source # foldr :: (a0 -> b -> b) -> b -> Either a a0 -> b Source # foldr' :: (a0 -> b -> b) -> b -> Either a a0 -> b Source # foldl :: (b -> a0 -> b) -> b -> Either a a0 -> b Source # foldl' :: (b -> a0 -> b) -> b -> Either a a0 -> b Source # foldr1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 Source # foldl1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 Source # toList :: Either a a0 -> [a0] Source # null :: Either a a0 -> Bool Source # length :: Either a a0 -> Int Source # elem :: Eq a0 => a0 -> Either a a0 -> Bool Source # maximum :: Ord a0 => Either a a0 -> a0 Source # minimum :: Ord a0 => Either a a0 -> a0 Source # | |||||

Traversable (Either a) Source # | @since base-4.7.0.0 | ||||

Defined in GHC.Internal.Data.Traversable | |||||

Semigroup (Either a b) Source # | @since base-4.9.0.0 | ||||

(Data a, Data b) => Data (Either a b) Source # | @since base-4.0.0.0 | ||||

Defined in GHC.Internal.Data.Data gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Either a b -> c (Either a b) Source # gunfold :: (forall b0 r. Data b0 => c (b0 -> 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 b0. Data b0 => b0 -> b0) -> Either a b -> Either a b Source # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r Source # gmapQr :: forall r r'. (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 # | |||||

Generic (Either a b) Source # | |||||

Defined in GHC.Internal.Generics
| |||||

(Read a, Read b) => Read (Either a b) Source # | @since base-3.0 | ||||

(Show a, Show b) => Show (Either a b) Source # | @since base-3.0 | ||||

(Eq a, Eq b) => Eq (Either a b) Source # | @since base-2.01 | ||||

(Ord a, Ord b) => Ord (Either a b) Source # | @since base-2.01 | ||||

Defined in GHC.Internal.Data.Either 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 # | |||||

type Rep1 (Either a :: Type -> Type) Source # | @since base-4.6.0.0 | ||||

Defined in GHC.Internal.Generics type Rep1 (Either a :: Type -> Type) = D1 ('MetaData "Either" "GHC.Internal.Data.Either" "ghc-internal" 'False) (C1 ('MetaCons "Left" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1)) | |||||

type Rep (Either a b) Source # | @since base-4.6.0.0 | ||||

Defined in GHC.Internal.Generics type Rep (Either a b) = D1 ('MetaData "Either" "GHC.Internal.Data.Either" "ghc-internal" 'False) (C1 ('MetaCons "Left" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 b))) |

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

Case analysis for the `Either`

type.
If the value is

, apply the first function to `Left`

a`a`

;
if it is

, apply the second function to `Right`

b`b`

.

#### Examples

We create two values of type

, one using the
`Either`

`String`

`Int`

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

`>>>`

3`either length (*2) s`

`>>>`

6`either length (*2) n`

isLeft :: Either a b -> Bool Source #

Return `True`

if the given value is a `Left`

-value, `False`

otherwise.

@since base-4.7.0.0

#### Examples

Basic usage:

`>>>`

True`isLeft (Left "foo")`

`>>>`

False`isLeft (Right 3)`

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

`>>>`

ERROR`report (Left "parse error")`

isRight :: Either a b -> Bool Source #

Return `True`

if the given value is a `Right`

-value, `False`

otherwise.

@since base-4.7.0.0

#### Examples

Basic usage:

`>>>`

False`isRight (Left "foo")`

`>>>`

True`isRight (Right 3)`

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")`

`>>>`

SUCCESS`report (Right 1)`

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

Return the contents of a `Left`

-value or a default value otherwise.

@since base-4.10.0.0

#### Examples

Basic usage:

`>>>`

3`fromLeft 1 (Left 3)`

`>>>`

1`fromLeft 1 (Right "foo")`

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

Return the contents of a `Right`

-value or a default value otherwise.

@since base-4.10.0.0

#### Examples

Basic usage:

`>>>`

3`fromRight 1 (Right 3)`

`>>>`

1`fromRight 1 (Left "foo")`

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" ]`

`>>>`

(["foo","bar","baz"],[3,7])`partitionEithers list`

The pair returned by

should be the same
pair as `partitionEithers`

x`(`

:`lefts`

x, `rights`

x)

`>>>`

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

`>>>`

True`partitionEithers list == (lefts list, rights list)`