variant-1.0.2: Variant and EADT
Safe HaskellNone
LanguageHaskell2010

Data.Variant.VEither

Description

Variant biased towards one type

Variants have types like V [W,X,Y,Z]. This is great when all the inner types play the same role. However in some cases we want one type to be the main one and the other ones to be secondaries.

For instance we could have V [Result,ErrorA,ErrorB,ErrorC] to represent the result of a function. In this case, the first type is the main one and it would be great to be able to define the common type-classes (Functor, Monad, etc.) so that we have easy access to it.

VEither is a V wrapper that does exactly this:

newtype VEither es a = VEither (V (a : es))

It is isomorphic to Either (V es) a. The difference is in the runtime representation: VEither es a has one less indirection than Either (V es) a (it uses only one tag value).

Pattern matching (VRight and VLeft)

VEither values can be created and matched on with the VRight and VLeft patterns (just as if we had the Either (V es) a type).

>>> VRight True :: VEither [String,Int] Bool
VRight True

>>> VLeft (V "failed" :: V [String,Int]) :: VEither [String,Int] Bool
VLeft "failed"

Common instances

The main advantage of VEither es a over V (a ': es) is that we can define instances for common type-classes such as Functor, Applicative, Monad, Foldable, etc.:

> let x = VRight True :: VEither [Int,Float] Bool
> fmap (\b -> if b then "Success" else "Failure") x
VRight "Success"

> let x = VRight True  :: VEither [Int,Float] Bool
> let y = VRight False :: VEither [Int,Float] Bool
> (&&) \<$> x \<*> y
VRight False

> let x   = VRight True    :: VEither [Int,Float] Bool
> let f v = VRight (not v) :: VEither [Int,Float] Bool
> x >>= f
VRight False

> let x = VRight True :: VEither [Int,Float] Bool
> let y = VLeft (V "failed" :: V [String,Int]) :: VEither [String,Int] Bool
> forM_ x print
True
> forM_ y print

See also

Synopsis

Documentation

data VEither (es :: [Type]) a Source #

Variant biased towards one type

Instances

Instances details
Foldable (VEither es) Source #

Foldable instance for VEither

>>> let x   = VRight True    :: VEither [Int,Float] Bool
>>> let y   = VLeft (V "failed" :: V [String,Int]) :: VEither [String,Int] Bool
>>> forM_ x print
True
>>> forM_ y print
Instance details

Defined in Data.Variant.VEither

Methods

fold :: Monoid m => VEither es m -> m #

foldMap :: Monoid m => (a -> m) -> VEither es a -> m #

foldMap' :: Monoid m => (a -> m) -> VEither es a -> m #

foldr :: (a -> b -> b) -> b -> VEither es a -> b #

foldr' :: (a -> b -> b) -> b -> VEither es a -> b #

foldl :: (b -> a -> b) -> b -> VEither es a -> b #

foldl' :: (b -> a -> b) -> b -> VEither es a -> b #

foldr1 :: (a -> a -> a) -> VEither es a -> a #

foldl1 :: (a -> a -> a) -> VEither es a -> a #

toList :: VEither es a -> [a] #

null :: VEither es a -> Bool #

length :: VEither es a -> Int #

elem :: Eq a => a -> VEither es a -> Bool #

maximum :: Ord a => VEither es a -> a #

minimum :: Ord a => VEither es a -> a #

sum :: Num a => VEither es a -> a #

product :: Num a => VEither es a -> a #

Traversable (VEither es) Source # 
Instance details

Defined in Data.Variant.VEither

Methods

traverse :: Applicative f => (a -> f b) -> VEither es a -> f (VEither es b) #

sequenceA :: Applicative f => VEither es (f a) -> f (VEither es a) #

mapM :: Monad m => (a -> m b) -> VEither es a -> m (VEither es b) #

sequence :: Monad m => VEither es (m a) -> m (VEither es a) #

Applicative (VEither es) Source #

Applicative instance for VEither

>>> let x = VRight True  :: VEither [Int,Float] Bool
>>> let y = VRight False :: VEither [Int,Float] Bool
>>> (&&) <$> x <*> y
VRight False
>>> (||) <$> x <*> y
VRight True
Instance details

Defined in Data.Variant.VEither

Methods

pure :: a -> VEither es a #

(<*>) :: VEither es (a -> b) -> VEither es a -> VEither es b #

liftA2 :: (a -> b -> c) -> VEither es a -> VEither es b -> VEither es c #

(*>) :: VEither es a -> VEither es b -> VEither es b #

(<*) :: VEither es a -> VEither es b -> VEither es a #

Functor (VEither es) Source #

Functor instance for VEither

>>> let x = VRight True :: VEither [Int,Float] Bool
>>> fmap (\b -> if b then "Success" else "Failure") x
VRight "Success"
Instance details

Defined in Data.Variant.VEither

Methods

fmap :: (a -> b) -> VEither es a -> VEither es b #

(<$) :: a -> VEither es b -> VEither es a #

Monad (VEither es) Source #

Monad instance for VEither

>>> let x   = VRight True    :: VEither [Int,Float] Bool
>>> let f v = VRight (not v) :: VEither [Int,Float] Bool
>>> x >>= f
VRight False
Instance details

Defined in Data.Variant.VEither

Methods

(>>=) :: VEither es a -> (a -> VEither es b) -> VEither es b #

(>>) :: VEither es a -> VEither es b -> VEither es b #

return :: a -> VEither es a #

(Show a, Show (V es)) => Show (VEither es a) Source # 
Instance details

Defined in Data.Variant.VEither

Methods

showsPrec :: Int -> VEither es a -> ShowS #

show :: VEither es a -> String #

showList :: [VEither es a] -> ShowS #

Eq (V (a ': es)) => Eq (VEither es a) Source #

Check VEithers for equality

>>> let a = VRight "Foo" :: VEither [Int,Double] String
>>> let b = VRight "Foo" :: VEither [Int,Double] String
>>> let c = VRight "Bar" :: VEither [Int,Double] String
>>> let d = VLeft (V (1::Int) :: V [Int, Double]) :: VEither [Int,Double] String
>>> a == b
True
>>> a == c
False
>>> a == d
False
Instance details

Defined in Data.Variant.VEither

Methods

(==) :: VEither es a -> VEither es a -> Bool #

(/=) :: VEither es a -> VEither es a -> Bool #

Ord (V (a ': es)) => Ord (VEither es a) Source #

Compare VEithers

>>> let a = VRight "Foo" :: VEither [Int,Double] String
>>> let b = VRight "Bar" :: VEither [Int,Double] String
>>> a < b
False
>>> a > b
True
Instance details

Defined in Data.Variant.VEither

Methods

compare :: VEither es a -> VEither es a -> Ordering #

(<) :: VEither es a -> VEither es a -> Bool #

(<=) :: VEither es a -> VEither es a -> Bool #

(>) :: VEither es a -> VEither es a -> Bool #

(>=) :: VEither es a -> VEither es a -> Bool #

max :: VEither es a -> VEither es a -> VEither es a #

min :: VEither es a -> VEither es a -> VEither es a #

pattern VLeft :: forall x xs. V xs -> VEither xs x Source #

Left value

>>> VLeft (V "failed" :: V [String,Int]) :: VEither [String,Int] Bool
VLeft "failed"

pattern VRight :: x -> VEither xs x Source #

Right value

>>> VRight True :: VEither [String,Int] Bool
VRight True

veitherFromVariant :: forall a (es :: [Type]). V (a ': es) -> VEither es a Source #

Convert a Variant into a VEither

>>> let x = V "Test" :: V [Int,String,Double]
>>> veitherFromVariant x
VLeft "Test"

veitherToVariant :: forall (es :: [Type]) a. VEither es a -> V (a ': es) Source #

Convert a VEither into a Variant

>>> let x = VRight True :: VEither [Int,Float] Bool
>>> veitherToVariant x
True

veitherToValue :: VEither ('[] :: [Type]) a -> a Source #

Extract from a VEither without left types

>>> let x = VRight True :: VEither '[] Bool
>>> veitherToValue x
True

veitherBimap :: forall (es :: [Type]) (fs :: [Type]) a b. (V es -> V fs) -> (a -> b) -> VEither es a -> VEither fs b Source #

Bimap for VEither

>>> let x = VRight True :: VEither [Int,Float] Bool
>>> veitherBimap id not x
VRight False

type VEitherLift (es :: [Type]) (es' :: [Type]) = LiftVariant es es' Source #

veitherLift :: forall (es' :: [Type]) (es :: [Type]) a. VEitherLift es es' => VEither es a -> VEither es' a Source #

Lift a VEither into another

veitherAppend :: forall (ns :: [Type]) (es :: [Type]) a. VEither es a -> VEither (Concat es ns) a Source #

Append errors to VEither

veitherPrepend :: forall (ns :: [Type]) (es :: [Type]) a. KnownNat (Length ns) => VEither es a -> VEither (Concat ns es) a Source #

Prepend errors to VEither

veitherCont :: forall (es :: [Type]) u a. (V es -> u) -> (a -> u) -> VEither es a -> u Source #

VEither continuations

veitherToEither :: forall (es :: [Type]) a. VEither es a -> Either (V es) a Source #

Convert a VEither into an Either

>>> let x = VRight True :: VEither [Int,Float] Bool
>>> veitherToEither x
Right True

veitherProduct :: forall b (e2 :: [Type]) (e1 :: [Type]) a. KnownNat (Length (b ': e2)) => VEither e1 a -> VEither e2 b -> VEither (Tail (Product (a ': e1) (b ': e2))) (a, b) Source #

Product of two VEither