| 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
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>>>sLeft "foo">>>let n = Right 3 :: Either String Int>>>nRight 3>>>:type ss :: Either String Int>>>:type nn :: 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) sLeft "foo">>>fmap (*2) nRight 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)>>>:}
>>>parseMultipleRight 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)>>>:}
>>>parseMultipleLeft "parse error"
Instances
Methods
fold :: Monoid m => Either a m -> m Source
foldMap :: Monoid m => (b -> m) -> Either a b -> m Source
foldr :: (b -> c -> c) -> c -> Either a b -> c Source
foldr' :: (b -> c -> c) -> c -> Either a b -> c Source
foldl :: (b -> c -> b) -> b -> Either a c -> b Source
foldl' :: (b -> c -> b) -> b -> Either a c -> b Source
foldr1 :: (b -> b -> b) -> Either a b -> b Source
foldl1 :: (b -> b -> b) -> Either a b -> b Source
toList :: Either a b -> [b] Source
null :: Either a b -> Bool Source
length :: Either a b -> Int Source
elem :: Eq b => b -> Either a b -> Bool Source
maximum :: Ord b => Either a b -> b Source
minimum :: Ord b => Either a b -> b Source
Methods
gfoldl :: (forall d e. Data d => c (d -> e) -> d -> c e) -> (forall g. g -> c g) -> Either a b -> c (Either a b) Source
gunfold :: (forall d r. Data d => c (d -> 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
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 aa;
if it is , apply the second function to Right bb.
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>>>either length (*2) s3>>>either length (*2) n6
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 should be the same
pair as partitionEithers x(:lefts x, rights x)
>>>let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]>>>partitionEithers list == (lefts list, rights list)True