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

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

Maintainer | [email protected] |

Stability | experimental |

Portability | portable |

Safe Haskell | Trustworthy |

Language | Haskell2010 |

The Either type, and associated operations.

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

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`

`>>>`

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`

Bifunctor Either | |

Monad (Either e) | |

Functor (Either a) | |

MonadFix (Either e) | |

Applicative (Either e) | |

Foldable (Either a) | |

Traversable (Either a) | |

Generic1 (Either a) | |

(Eq a, Eq b) => Eq (Either a b) | |

(Data a, Data b) => Data (Either a b) | |

(Ord a, Ord b) => Ord (Either a b) | |

(Read a, Read b) => Read (Either a b) | |

(Show a, Show b) => Show (Either a b) | |

Generic (Either a b) | |

type Rep1 (Either a) | |

type Rep (Either 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`

.

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`

`>>>`

3`either length (*2) s`

`>>>`

6`either length (*2) n`

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

Extracts from a list of `Either`

all the `Left`

elements. All the `Left`

elements are extracted in order.

Basic usage:

`>>>`

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

`>>>`

["foo","bar","baz"]`lefts list`

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

Extracts from a list of `Either`

all the `Right`

elements. All the `Right`

elements are extracted in order.

Basic usage:

`>>>`

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

`>>>`

[3,7]`rights list`

isLeft :: Either a b -> Bool Source

Return `True`

if the given value is a `Left`

-value, `False`

otherwise.

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

Since: 4.7.0.0

isRight :: Either a b -> Bool Source

Return `True`

if the given value is a `Right`

-value, `False`

otherwise.

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

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.

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

should be the same pair as `(lefts x, rights x)`

:

`>>>`

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

`>>>`

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

© The University of Glasgow and others

Licensed under a BSD-style license (see top of the page).

https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/base-4.8.2.0/Data-Either.html