| Copyright | (c) Erich Gut |
|---|---|
| License | BSD3 |
| Maintainer | zerich.gut@gmail.com |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
OAlg.Data.Either
Description
disjoint union of data.
Either
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 | Since: base-4.10.0.0 | ||||
| Bifoldable1 Either | |||||
Defined in Data.Bifoldable1 | |||||
| Bifunctor Either | Since: base-4.8.0.0 | ||||
| Bitraversable Either | 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) # | |||||
| Eq2 Either | Since: base-4.9.0.0 | ||||
| Ord2 Either | Since: base-4.9.0.0 | ||||
Defined in Data.Functor.Classes | |||||
| Read2 Either | 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) # liftReadList2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> ReadS [Either a b] # liftReadPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec (Either a b) # liftReadListPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec [Either a b] # | |||||
| Show2 Either | Since: base-4.9.0.0 | ||||
| NFData2 Either | Since: deepseq-1.4.3.0 | ||||
Defined in Control.DeepSeq | |||||
| Generic1 (Either a :: Type -> Type) | |||||
Defined in GHC.Generics Associated Types
| |||||
| (Lift a, Lift b) => Lift (Either a b :: Type) | |||||
| MonadFix (Either e) | Since: base-4.3.0.0 | ||||
Defined in Control.Monad.Fix | |||||
| Foldable (Either a) | Since: base-4.7.0.0 | ||||
Defined in Data.Foldable Methods fold :: Monoid m => Either a m -> m # foldMap :: Monoid m => (a0 -> m) -> Either a a0 -> m # foldMap' :: Monoid m => (a0 -> m) -> Either a a0 -> m # foldr :: (a0 -> b -> b) -> b -> Either a a0 -> b # foldr' :: (a0 -> b -> b) -> b -> Either a a0 -> b # foldl :: (b -> a0 -> b) -> b -> Either a a0 -> b # foldl' :: (b -> a0 -> b) -> b -> Either a a0 -> b # foldr1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 # foldl1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 # toList :: Either a a0 -> [a0] # length :: Either a a0 -> Int # elem :: Eq a0 => a0 -> Either a a0 -> Bool # maximum :: Ord a0 => Either a a0 -> a0 # minimum :: Ord a0 => Either a a0 -> a0 # | |||||
| Eq a => Eq1 (Either a) | Since: base-4.9.0.0 | ||||
| Ord a => Ord1 (Either a) | Since: base-4.9.0.0 | ||||
Defined in Data.Functor.Classes | |||||
| Read a => Read1 (Either a) | Since: base-4.9.0.0 | ||||
Defined in Data.Functor.Classes Methods liftReadsPrec :: (Int -> ReadS a0) -> ReadS [a0] -> Int -> ReadS (Either a a0) # liftReadList :: (Int -> ReadS a0) -> ReadS [a0] -> ReadS [Either a a0] # liftReadPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec (Either a a0) # liftReadListPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec [Either a a0] # | |||||
| Show a => Show1 (Either a) | Since: base-4.9.0.0 | ||||
| Traversable (Either a) | Since: base-4.7.0.0 | ||||
Defined in Data.Traversable | |||||
| Applicative (Either e) | Since: base-3.0 | ||||
| Functor (Either a) | Since: base-3.0 | ||||
| Monad (Either e) | Since: base-4.4.0.0 | ||||
| NFData a => NFData1 (Either a) | Since: deepseq-1.4.3.0 | ||||
Defined in Control.DeepSeq | |||||
| (Data a, Data b) => Data (Either a b) | 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) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Either a b) # toConstr :: Either a b -> Constr # dataTypeOf :: Either a b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Either a b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Either a b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Either a b -> Either a b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r # gmapQ :: (forall d. Data d => d -> u) -> Either a b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Either a b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) # | |||||
| Semigroup (Either a b) | Since: base-4.9.0.0 | ||||
| Generic (Either a b) | |||||
Defined in GHC.Generics Associated Types
| |||||
| (Read a, Read b) => Read (Either a b) | Since: base-3.0 | ||||
| (Show a, Show b) => Show (Either a b) | Since: base-3.0 | ||||
| (NFData a, NFData b) => NFData (Either a b) | |||||
Defined in Control.DeepSeq | |||||
| (Eq a, Eq b) => Eq (Either a b) | Since: base-2.1 | ||||
| (Ord a, Ord b) => Ord (Either a b) | Since: base-2.1 | ||||
| (Validable a, Validable b) => Validable (Either a b) Source # | |||||
| (Finite a, Uniform a, Finite b, Uniform b) => Uniform (Either a b) | |||||
Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (Either a b) # | |||||
| type Rep1 (Either a :: Type -> Type) | 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) | 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 #
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
Either1
data Either1 (f :: Type -> Type) (g :: Type -> Type) x where Source #
disjoint union of two 1-parameterized data types.
Constructors
| Left1 :: forall (f :: Type -> Type) x (g :: Type -> Type). f x -> Either1 f g x | |
| Right1 :: forall (g :: Type -> Type) x (f :: Type -> Type). g x -> Either1 f g x |
Either2
data Either2 (f :: Type -> Type -> Type) (g :: Type -> Type -> Type) a b where Source #
disjoint union of two 2-parameterized data types.
Constructors
| Left2 :: forall (f :: Type -> Type -> Type) a b (g :: Type -> Type -> Type). f a b -> Either2 f g a b | |
| Right2 :: forall (g :: Type -> Type -> Type) a b (f :: Type -> Type -> Type). g a b -> Either2 f g a b |
Instances
| (ApplicativeG t f c, ApplicativeG t g c) => ApplicativeG t (Either2 f g) c Source # | |||||
Defined in OAlg.Category.Applicative | |||||
| (Morphism f, Morphism g, ObjectClass f ~ ObjectClass g) => Morphism (Either2 f g) Source # | |||||
Defined in OAlg.Category.Definition Associated Types
Methods homomorphous :: Either2 f g x y -> Homomorphous (ObjectClass (Either2 f g)) x y Source # domain :: Either2 f g x y -> Struct (ObjectClass (Either2 f g)) x Source # range :: Either2 f g x y -> Struct (ObjectClass (Either2 f g)) y Source # | |||||
| (Eq2 f, Eq2 g) => Eq2 (Either2 f g) Source # | |||||
| (Show2 f, Show2 g) => Show2 (Either2 f g) Source # | |||||
| (Validable2 f, Validable2 g) => Validable2 (Either2 f g) Source # | |||||
| (Show2 f, Show2 g) => Show (Either2 f g x y) Source # | |||||
| (Eq2 f, Eq2 g) => Eq (Either2 f g x y) Source # | |||||
| type ObjectClass (Either2 f g) Source # | |||||
Defined in OAlg.Category.Definition | |||||