| 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 |
Data.Either
Description
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 IntString or an Int. The Left constructor can be used only on Strings, and the Right constructor can be used only on Ints:
>>>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 Ints.
>>>:{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
| Bifoldable Either Source # | Since: base-4.10.0.0 |
Defined in Data.Bifoldable | |
| Bifunctor Either Source # | Since: base-4.8.0.0 |
| Bitraversable Either Source # | Since: base-4.10.0.0 |
Defined in Data.Bitraversable Methods bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d) Source # | |
| Eq2 Either Source # | Since: base-4.9.0.0 |
| Ord2 Either Source # | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
| Read2 Either Source # | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes 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 # liftReadPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec (Either a b) Source # liftReadListPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec [Either a b] Source # | |
| Show2 Either Source # | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
| Generic1 (Either a :: Type -> Type) Source # | |
| MonadFix (Either e) Source # | Since: base-4.3.0.0 |
| Foldable (Either a) Source # | Since: base-4.7.0.0 |
Defined in Data.Foldable Methods 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 # | |
| Eq a => Eq1 (Either a) Source # | Since: base-4.9.0.0 |
| Ord a => Ord1 (Either a) Source # | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
| Read a => Read1 (Either a) Source # | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes Methods liftReadsPrec :: (Int -> ReadS a0) -> ReadS [a0] -> Int -> ReadS (Either a a0) Source # liftReadList :: (Int -> ReadS a0) -> ReadS [a0] -> ReadS [Either a a0] Source # liftReadPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec (Either a a0) Source # liftReadListPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec [Either a a0] Source # | |
| Show a => Show1 (Either a) Source # | Since: base-4.9.0.0 |
| Traversable (Either a) Source # | Since: base-4.7.0.0 |
Defined in Data.Traversable Methods traverse :: Applicative f => (a0 -> f b) -> Either a a0 -> f (Either a b) Source # sequenceA :: Applicative f => Either a (f a0) -> f (Either a a0) Source # mapM :: Monad m => (a0 -> m b) -> Either a a0 -> m (Either a b) Source # sequence :: Monad m => Either a (m a0) -> m (Either a a0) Source # | |
| Applicative (Either e) Source # | Since: base-3.0 |
Defined in Data.Either | |
| Functor (Either a) Source # | Since: base-3.0 |
| Monad (Either e) Source # | Since: base-4.4.0.0 |
| (Data a, Data b) => Data (Either a b) Source # | Since: base-4.0.0.0 |
Defined in Data.Data Methods 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 # | |
| Semigroup (Either a b) Source # | Since: base-4.9.0.0 |
| Generic (Either a b) Source # | |
| (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.1 |
| (Ord a, Ord b) => Ord (Either a b) Source # | Since: base-2.1 |
Defined in Data.Either 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 # | |
| type Rep1 (Either a :: Type -> Type) Source # | Since: base-4.6.0.0 |
Defined in GHC.Generics type Rep1 (Either a :: Type -> Type) = D1 ('MetaData "Either" "Data.Either" "base" '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.Generics type Rep (Either a b) = D1 ('MetaData "Either" "Data.Either" "base" '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 aa; if it is , apply the second function to Right bb.
Examples
We create two values of type , one using the Either String IntLeft 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: base-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: base-4.7.0.0
fromLeft :: a -> Either a b -> a Source #
Return the contents of a Left-value or a default value otherwise.
Examples
Basic usage:
>>>fromLeft 1 (Left 3)3>>>fromLeft 1 (Right "foo")1
Since: base-4.10.0.0
fromRight :: b -> Either a b -> b Source #
Return the contents of a Right-value or a default value otherwise.
Examples
Basic usage:
>>>fromRight 1 (Right 3)3>>>fromRight 1 (Left "foo")1
Since: base-4.10.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