contravariant-1.4: Contravariant functors

Copyright(C) 2014-2015 Edward Kmett
LicenseBSD-style (see the file LICENSE)
MaintainerEdward Kmett <ekmett@gmail.com>
Stabilityprovisional
Portabilityportable
Safe HaskellSafe
LanguageHaskell98

Data.Functor.Contravariant.Divisible

Contents

Description

This module supplies contravariant analogues to the Applicative and Alternative classes.

Synopsis

Contravariant Applicative

class Contravariant f => Divisible f where #

A Divisible contravariant functor is the contravariant analogue of Applicative.

In denser jargon, a Divisible contravariant functor is a monoid object in the category of presheaves from Hask to Hask, equipped with Day convolution mapping the Cartesian product of the source to the Cartesian product of the target.

By way of contrast, an Applicative functor can be viewed as a monoid object in the category of copresheaves from Hask to Hask, equipped with Day convolution mapping the Cartesian product of the source to the Cartesian product of the target.

Given the canonical diagonal morphism:

delta a = (a,a)

divide delta should be associative with conquer as a unit

divide delta m conquer = m
divide delta conquer m = m
divide delta (divide delta m n) o = divide delta m (divide delta n o)

With more general arguments you'll need to reassociate and project using the monoidal structure of the source category. (Here fst and snd are used in lieu of the more restricted lambda and rho, but this construction works with just a monoidal category.)

divide f m conquer = contramap (fst . f) m
divide f conquer m = contramap (snd . f) m
divide f (divide g m n) o = divide f' m (divide id n o) where
  f' a = case f a of (bc,d) -> case g bc of (b,c) -> (a,(b,c))

Minimal complete definition

divide, conquer

Methods

divide :: (a -> (b, c)) -> f b -> f c -> f a #

conquer :: f a #

The underlying theory would suggest that this should be:

conquer :: (a -> ()) -> f a

However, as we are working over a Cartesian category (Hask) and the Cartesian product, such an input morphism is uniquely determined to be const mempty, so we elide it.

Instances

Divisible U1 # 

Methods

divide :: (a -> (b, c)) -> U1 b -> U1 c -> U1 a #

conquer :: U1 a #

Divisible Equivalence # 

Methods

divide :: (a -> (b, c)) -> Equivalence b -> Equivalence c -> Equivalence a #

conquer :: Equivalence a #

Divisible Comparison # 

Methods

divide :: (a -> (b, c)) -> Comparison b -> Comparison c -> Comparison a #

conquer :: Comparison a #

Divisible Predicate # 

Methods

divide :: (a -> (b, c)) -> Predicate b -> Predicate c -> Predicate a #

conquer :: Predicate a #

Divisible f => Divisible (Rec1 f) # 

Methods

divide :: (a -> (b, c)) -> Rec1 f b -> Rec1 f c -> Rec1 f a #

conquer :: Rec1 f a #

Divisible (Proxy *) # 

Methods

divide :: (a -> (b, c)) -> Proxy * b -> Proxy * c -> Proxy * a #

conquer :: Proxy * a #

Divisible m => Divisible (MaybeT m) # 

Methods

divide :: (a -> (b, c)) -> MaybeT m b -> MaybeT m c -> MaybeT m a #

conquer :: MaybeT m a #

Divisible m => Divisible (ListT m) # 

Methods

divide :: (a -> (b, c)) -> ListT m b -> ListT m c -> ListT m a #

conquer :: ListT m a #

Monoid r => Divisible (Op r) # 

Methods

divide :: (a -> (b, c)) -> Op r b -> Op r c -> Op r a #

conquer :: Op r a #

(Divisible f, Divisible g) => Divisible ((:*:) f g) # 

Methods

divide :: (a -> (b, c)) -> (f :*: g) b -> (f :*: g) c -> (f :*: g) a #

conquer :: (f :*: g) a #

(Applicative f, Divisible g) => Divisible ((:.:) f g) # 

Methods

divide :: (a -> (b, c)) -> (f :.: g) b -> (f :.: g) c -> (f :.: g) a #

conquer :: (f :.: g) a #

Monoid m => Divisible (Const * m) # 

Methods

divide :: (a -> (b, c)) -> Const * m b -> Const * m c -> Const * m a #

conquer :: Const * m a #

Divisible f => Divisible (Alt * f) # 

Methods

divide :: (a -> (b, c)) -> Alt * f b -> Alt * f c -> Alt * f a #

conquer :: Alt * f a #

Divisible f => Divisible (Reverse * f) # 

Methods

divide :: (a -> (b, c)) -> Reverse * f b -> Reverse * f c -> Reverse * f a #

conquer :: Reverse * f a #

Divisible f => Divisible (Backwards * f) # 

Methods

divide :: (a -> (b, c)) -> Backwards * f b -> Backwards * f c -> Backwards * f a #

conquer :: Backwards * f a #

Divisible m => Divisible (WriterT w m) # 

Methods

divide :: (a -> (b, c)) -> WriterT w m b -> WriterT w m c -> WriterT w m a #

conquer :: WriterT w m a #

Divisible m => Divisible (WriterT w m) # 

Methods

divide :: (a -> (b, c)) -> WriterT w m b -> WriterT w m c -> WriterT w m a #

conquer :: WriterT w m a #

Divisible m => Divisible (StateT s m) # 

Methods

divide :: (a -> (b, c)) -> StateT s m b -> StateT s m c -> StateT s m a #

conquer :: StateT s m a #

Divisible m => Divisible (StateT s m) # 

Methods

divide :: (a -> (b, c)) -> StateT s m b -> StateT s m c -> StateT s m a #

conquer :: StateT s m a #

Divisible f => Divisible (IdentityT * f) # 

Methods

divide :: (a -> (b, c)) -> IdentityT * f b -> IdentityT * f c -> IdentityT * f a #

conquer :: IdentityT * f a #

Divisible m => Divisible (ExceptT e m) # 

Methods

divide :: (a -> (b, c)) -> ExceptT e m b -> ExceptT e m c -> ExceptT e m a #

conquer :: ExceptT e m a #

Divisible m => Divisible (ErrorT e m) # 

Methods

divide :: (a -> (b, c)) -> ErrorT e m b -> ErrorT e m c -> ErrorT e m a #

conquer :: ErrorT e m a #

Monoid m => Divisible (Constant * m) # 

Methods

divide :: (a -> (b, c)) -> Constant * m b -> Constant * m c -> Constant * m a #

conquer :: Constant * m a #

(Divisible f, Applicative g) => Divisible (ComposeCF f g) # 

Methods

divide :: (a -> (b, c)) -> ComposeCF f g b -> ComposeCF f g c -> ComposeCF f g a #

conquer :: ComposeCF f g a #

(Applicative f, Divisible g) => Divisible (ComposeFC f g) # 

Methods

divide :: (a -> (b, c)) -> ComposeFC f g b -> ComposeFC f g c -> ComposeFC f g a #

conquer :: ComposeFC f g a #

Divisible f => Divisible (M1 i c f) # 

Methods

divide :: (a -> (b, c)) -> M1 i c f b -> M1 i c f c -> M1 i c f a #

conquer :: M1 i c f a #

(Divisible f, Divisible g) => Divisible (Product * f g) # 

Methods

divide :: (a -> (b, c)) -> Product * f g b -> Product * f g c -> Product * f g a #

conquer :: Product * f g a #

Divisible m => Divisible (ReaderT * r m) # 

Methods

divide :: (a -> (b, c)) -> ReaderT * r m b -> ReaderT * r m c -> ReaderT * r m a #

conquer :: ReaderT * r m a #

(Applicative f, Divisible g) => Divisible (Compose * * f g) # 

Methods

divide :: (a -> (b, c)) -> Compose * * f g b -> Compose * * f g c -> Compose * * f g a #

conquer :: Compose * * f g a #

Divisible m => Divisible (RWST r w s m) # 

Methods

divide :: (a -> (b, c)) -> RWST r w s m b -> RWST r w s m c -> RWST r w s m a #

conquer :: RWST r w s m a #

Divisible m => Divisible (RWST r w s m) # 

Methods

divide :: (a -> (b, c)) -> RWST r w s m b -> RWST r w s m c -> RWST r w s m a #

conquer :: RWST r w s m a #

divided :: Divisible f => f a -> f b -> f (a, b) #

conquered :: Divisible f => f () #

Redundant, but provided for symmetry.

conquered = conquer

liftD :: Divisible f => (a -> b) -> f b -> f a #

This is the divisible analogue of liftA. It gives a viable default definition for contramap in terms of the members of Divisible.

liftD f = divide ((,) () . f) conquer

Contravariant Alternative

class Divisible f => Decidable f where #

A Divisible contravariant functor is a monoid object in the category of presheaves from Hask to Hask, equipped with Day convolution mapping the cartesian product of the source to the Cartesian product of the target.

choose Left m (lose f)  = m
choose Right (lose f) m = m
choose f (choose g m n) o = divide f' m (divide id n o) where
  f' bcd = either (either id (Right . Left) . g) (Right . Right) . f

In addition, we expect the same kind of distributive law as is satisfied by the usual covariant Alternative, w.r.t Applicative, which should be fully formulated and added here at some point!

Minimal complete definition

lose, choose

Methods

lose :: (a -> Void) -> f a #

The only way to win is not to play.

choose :: (a -> Either b c) -> f b -> f c -> f a #

Instances

Decidable U1 # 

Methods

lose :: (a -> Void) -> U1 a #

choose :: (a -> Either b c) -> U1 b -> U1 c -> U1 a #

Decidable Equivalence # 

Methods

lose :: (a -> Void) -> Equivalence a #

choose :: (a -> Either b c) -> Equivalence b -> Equivalence c -> Equivalence a #

Decidable Comparison # 

Methods

lose :: (a -> Void) -> Comparison a #

choose :: (a -> Either b c) -> Comparison b -> Comparison c -> Comparison a #

Decidable Predicate # 

Methods

lose :: (a -> Void) -> Predicate a #

choose :: (a -> Either b c) -> Predicate b -> Predicate c -> Predicate a #

Decidable f => Decidable (Rec1 f) # 

Methods

lose :: (a -> Void) -> Rec1 f a #

choose :: (a -> Either b c) -> Rec1 f b -> Rec1 f c -> Rec1 f a #

Decidable (Proxy *) # 

Methods

lose :: (a -> Void) -> Proxy * a #

choose :: (a -> Either b c) -> Proxy * b -> Proxy * c -> Proxy * a #

Divisible m => Decidable (MaybeT m) # 

Methods

lose :: (a -> Void) -> MaybeT m a #

choose :: (a -> Either b c) -> MaybeT m b -> MaybeT m c -> MaybeT m a #

Divisible m => Decidable (ListT m) # 

Methods

lose :: (a -> Void) -> ListT m a #

choose :: (a -> Either b c) -> ListT m b -> ListT m c -> ListT m a #

Monoid r => Decidable (Op r) # 

Methods

lose :: (a -> Void) -> Op r a #

choose :: (a -> Either b c) -> Op r b -> Op r c -> Op r a #

(Decidable f, Decidable g) => Decidable ((:*:) f g) # 

Methods

lose :: (a -> Void) -> (f :*: g) a #

choose :: (a -> Either b c) -> (f :*: g) b -> (f :*: g) c -> (f :*: g) a #

(Applicative f, Decidable g) => Decidable ((:.:) f g) # 

Methods

lose :: (a -> Void) -> (f :.: g) a #

choose :: (a -> Either b c) -> (f :.: g) b -> (f :.: g) c -> (f :.: g) a #

Decidable f => Decidable (Alt * f) # 

Methods

lose :: (a -> Void) -> Alt * f a #

choose :: (a -> Either b c) -> Alt * f b -> Alt * f c -> Alt * f a #

Decidable f => Decidable (Reverse * f) # 

Methods

lose :: (a -> Void) -> Reverse * f a #

choose :: (a -> Either b c) -> Reverse * f b -> Reverse * f c -> Reverse * f a #

Decidable f => Decidable (Backwards * f) # 

Methods

lose :: (a -> Void) -> Backwards * f a #

choose :: (a -> Either b c) -> Backwards * f b -> Backwards * f c -> Backwards * f a #

Decidable m => Decidable (WriterT w m) # 

Methods

lose :: (a -> Void) -> WriterT w m a #

choose :: (a -> Either b c) -> WriterT w m b -> WriterT w m c -> WriterT w m a #

Decidable m => Decidable (WriterT w m) # 

Methods

lose :: (a -> Void) -> WriterT w m a #

choose :: (a -> Either b c) -> WriterT w m b -> WriterT w m c -> WriterT w m a #

Decidable m => Decidable (StateT s m) # 

Methods

lose :: (a -> Void) -> StateT s m a #

choose :: (a -> Either b c) -> StateT s m b -> StateT s m c -> StateT s m a #

Decidable m => Decidable (StateT s m) # 

Methods

lose :: (a -> Void) -> StateT s m a #

choose :: (a -> Either b c) -> StateT s m b -> StateT s m c -> StateT s m a #

Decidable f => Decidable (IdentityT * f) # 

Methods

lose :: (a -> Void) -> IdentityT * f a #

choose :: (a -> Either b c) -> IdentityT * f b -> IdentityT * f c -> IdentityT * f a #

(Applicative f, Decidable g) => Decidable (ComposeFC f g) # 

Methods

lose :: (a -> Void) -> ComposeFC f g a #

choose :: (a -> Either b c) -> ComposeFC f g b -> ComposeFC f g c -> ComposeFC f g a #

Decidable f => Decidable (M1 i c f) # 

Methods

lose :: (a -> Void) -> M1 i c f a #

choose :: (a -> Either b c) -> M1 i c f b -> M1 i c f c -> M1 i c f a #

(Decidable f, Decidable g) => Decidable (Product * f g) # 

Methods

lose :: (a -> Void) -> Product * f g a #

choose :: (a -> Either b c) -> Product * f g b -> Product * f g c -> Product * f g a #

Decidable m => Decidable (ReaderT * r m) # 

Methods

lose :: (a -> Void) -> ReaderT * r m a #

choose :: (a -> Either b c) -> ReaderT * r m b -> ReaderT * r m c -> ReaderT * r m a #

(Applicative f, Decidable g) => Decidable (Compose * * f g) # 

Methods

lose :: (a -> Void) -> Compose * * f g a #

choose :: (a -> Either b c) -> Compose * * f g b -> Compose * * f g c -> Compose * * f g a #

Decidable m => Decidable (RWST r w s m) # 

Methods

lose :: (a -> Void) -> RWST r w s m a #

choose :: (a -> Either b c) -> RWST r w s m b -> RWST r w s m c -> RWST r w s m a #

Decidable m => Decidable (RWST r w s m) # 

Methods

lose :: (a -> Void) -> RWST r w s m a #

choose :: (a -> Either b c) -> RWST r w s m b -> RWST r w s m c -> RWST r w s m a #

chosen :: Decidable f => f b -> f c -> f (Either b c) #