base-4.8.0.0: Basic libraries

Data.Either

Description

The Either type, and associated operations.

Synopsis

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

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