-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Contravariant functors
--   
--   Contravariant functors
@package contravariant
@version 1.3.2


-- | <a>Contravariant</a> functors, sometimes referred to colloquially as
--   <tt>Cofunctor</tt>, even though the dual of a <a>Functor</a> is just a
--   <a>Functor</a>. As with <a>Functor</a> the definition of
--   <a>Contravariant</a> for a given ADT is unambiguous.
module Data.Functor.Contravariant

-- | Any instance should be subject to the following laws:
--   
--   <pre>
--   contramap id = id
--   contramap f . contramap g = contramap (g . f)
--   </pre>
--   
--   Note, that the second law follows from the free theorem of the type of
--   <a>contramap</a> and the first law, so you need only check that the
--   former condition holds.
class Contravariant f where (>$) = contramap . const
contramap :: Contravariant f => (a -> b) -> f b -> f a
(>$) :: Contravariant f => b -> f b -> f a

-- | If <tt>f</tt> is both <a>Functor</a> and <a>Contravariant</a> then by
--   the time you factor in the laws of each of those classes, it can't
--   actually use it's argument in any meaningful capacity.
--   
--   This method is surprisingly useful. Where both instances exist and are
--   lawful we have the following laws:
--   
--   <pre>
--   <a>fmap</a> f ≡ <a>phantom</a>
--   <a>contramap</a> f ≡ <a>phantom</a>
--   </pre>
phantom :: (Functor f, Contravariant f) => f a -> f b

-- | This is an infix alias for <a>contramap</a>
(>$<) :: Contravariant f => (a -> b) -> f b -> f a

-- | This is an infix version of <a>contramap</a> with the arguments
--   flipped.
(>$$<) :: Contravariant f => f b -> (a -> b) -> f a

-- | This is <a>&gt;$</a> with its arguments flipped.
($<) :: Contravariant f => f b -> b -> f a
newtype Predicate a
Predicate :: (a -> Bool) -> Predicate a
getPredicate :: Predicate a -> a -> Bool

-- | Defines a total ordering on a type as per <a>compare</a>
--   
--   This condition is not checked by the types. You must ensure that the
--   supplied values are valid total orderings yourself.
newtype Comparison a
Comparison :: (a -> a -> Ordering) -> Comparison a
getComparison :: Comparison a -> a -> a -> Ordering

-- | Compare using <a>compare</a>
defaultComparison :: Ord a => Comparison a

-- | This data type represents an equivalence relation.
--   
--   Equivalence relations are expected to satisfy three laws:
--   
--   <b>Reflexivity</b>:
--   
--   <pre>
--   <a>getEquivalence</a> f a a = True
--   </pre>
--   
--   <b>Symmetry</b>:
--   
--   <pre>
--   <a>getEquivalence</a> f a b = <a>getEquivalence</a> f b a
--   </pre>
--   
--   <b>Transitivity</b>:
--   
--   If <tt><a>getEquivalence</a> f a b</tt> and <tt><a>getEquivalence</a>
--   f b c</tt> are both <a>True</a> then so is <tt><a>getEquivalence</a> f
--   a c</tt>
--   
--   The types alone do not enforce these laws, so you'll have to check
--   them yourself.
newtype Equivalence a
Equivalence :: (a -> a -> Bool) -> Equivalence a
getEquivalence :: Equivalence a -> a -> a -> Bool

-- | Check for equivalence with <a>==</a>
--   
--   Note: The instances for <a>Double</a> and <a>Float</a> violate
--   reflexivity for <tt>NaN</tt>.
defaultEquivalence :: Eq a => Equivalence a
comparisonEquivalence :: Comparison a -> Equivalence a

-- | Dual function arrows.
newtype Op a b
Op :: (b -> a) -> Op a b
getOp :: Op a b -> b -> a
instance [safe] Typeable Predicate
instance [safe] Typeable Comparison
instance [safe] Typeable Equivalence
instance [safe] Typeable Op
instance [safe] Floating a => Floating (Op a b)
instance [safe] Fractional a => Fractional (Op a b)
instance [safe] Num a => Num (Op a b)
instance [safe] Monoid a => Monoid (Op a b)
instance [safe] Semigroup a => Semigroup (Op a b)
instance [safe] Contravariant (Op a)
instance [safe] Category Op
instance [safe] Monoid (Equivalence a)
instance [safe] Semigroup (Equivalence a)
instance [safe] Contravariant Equivalence
instance [safe] Monoid (Comparison a)
instance [safe] Semigroup (Comparison a)
instance [safe] Contravariant Comparison
instance [safe] Contravariant Predicate
instance [safe] Contravariant Proxy
instance [safe] Contravariant SettableStateVar
instance [safe] Contravariant f => Contravariant (Reverse f)
instance [safe] Contravariant f => Contravariant (Backwards f)
instance [safe] (Functor f, Contravariant g) => Contravariant (Compose f g)
instance [safe] Contravariant (Const a)
instance [safe] Contravariant (Constant a)
instance [safe] (Contravariant f, Contravariant g) => Contravariant (Product f g)
instance [safe] (Contravariant f, Contravariant g) => Contravariant (Sum f g)
instance [safe] (Contravariant f, Contravariant g) => Contravariant (f :+: g)
instance [safe] (Functor f, Contravariant g) => Contravariant (f :.: g)
instance [safe] (Contravariant f, Contravariant g) => Contravariant (f :*: g)
instance [safe] Contravariant (K1 i c)
instance [safe] Contravariant f => Contravariant (M1 i c f)
instance [safe] Contravariant f => Contravariant (Rec1 f)
instance [safe] Contravariant U1
instance [safe] Contravariant V1


-- | This module supplies contravariant analogues to the
--   <tt>Applicative</tt> and <tt>Alternative</tt> classes.
module Data.Functor.Contravariant.Divisible

-- | A <a>Divisible</a> contravariant functor is the contravariant analogue
--   of <tt>Applicative</tt>.
--   
--   In denser jargon, a <a>Divisible</a> 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 <tt>Applicative</tt> 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:
--   
--   <pre>
--   delta a = (a,a)
--   </pre>
--   
--   <tt><a>divide</a> <tt>delta</tt></tt> should be associative with
--   <a>conquer</a> as a unit
--   
--   <pre>
--   <a>divide</a> <tt>delta</tt> m <a>conquer</a> = m
--   <a>divide</a> <tt>delta</tt> <a>conquer</a> m = m
--   <a>divide</a> <tt>delta</tt> (<a>divide</a> <tt>delta</tt> m n) o = <a>divide</a> <tt>delta</tt> m (<a>divide</a> <tt>delta</tt> n o)
--   </pre>
--   
--   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.)
--   
--   <pre>
--   <a>divide</a> f m <a>conquer</a> = <a>contramap</a> (<a>fst</a> . f) m
--   <a>divide</a> f <a>conquer</a> m = <a>contramap</a> (<a>snd</a> . f) m
--   <a>divide</a> f (<a>divide</a> g m n) o = <a>divide</a> f' m (<a>divide</a> <a>id</a> n o) where
--     f' a = case f a of (bc,d) -&gt; case g bc of (b,c) -&gt; (a,(b,c))
--   </pre>
class Contravariant f => Divisible f
divide :: Divisible f => (a -> (b, c)) -> f b -> f c -> f a
conquer :: Divisible f => f a

-- | <pre>
--   <a>divided</a> = <a>divide</a> <a>id</a>
--   </pre>
divided :: Divisible f => f a -> f b -> f (a, b)

-- | Redundant, but provided for symmetry.
--   
--   <pre>
--   <a>conquered</a> = 'conquer
--   </pre>
conquered :: Divisible f => f ()

-- | This is the divisible analogue of <tt>liftA</tt>. It gives a viable
--   default definition for <a>contramap</a> in terms of the members of
--   <a>Divisible</a>.
--   
--   <pre>
--   <a>liftD</a> f = <a>divide</a> ((,) () . f) <a>conquer</a>
--   </pre>
liftD :: Divisible f => (a -> b) -> f b -> f a

-- | A <a>Divisible</a> 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.
--   
--   <pre>
--   <a>choose</a> Left m (<a>lose</a> f)  = m
--   <a>choose</a> Right (<a>lose</a> f) m = m
--   <a>choose</a> f (<a>choose</a> g m n) o = <a>divide</a> f' m (<a>divide</a> <a>id</a> n o) where
--     f' bcd = <a>either</a> (<a>either</a> <a>id</a> (<a>Right</a> . <a>Left</a>) . g) (<a>Right</a> . <a>Right</a>) . f
--   </pre>
--   
--   In addition, we expect the same kind of distributive law as is
--   satisfied by the usual covariant <tt>Alternative</tt>, w.r.t
--   <tt>Applicative</tt>, which should be fully formulated and added here
--   at some point!
class Divisible f => Decidable f
lose :: Decidable f => (a -> Void) -> f a
choose :: Decidable f => (a -> Either b c) -> f b -> f c -> f a

-- | <pre>
--   <a>chosen</a> = <a>choose</a> <a>id</a>
--   </pre>
chosen :: Decidable f => f b -> f c -> f (Either b c)

-- | <pre>
--   <a>lost</a> = <a>lose</a> <a>id</a>
--   </pre>
lost :: Decidable f => f Void
instance Monoid r => Decidable (Op r)
instance Decidable Predicate
instance Decidable Equivalence
instance Decidable Comparison
instance Divisible Predicate
instance Divisible Equivalence
instance Divisible Comparison
instance Monoid r => Divisible (Op r)


-- | Composition of contravariant functors.
module Data.Functor.Contravariant.Compose

-- | Composition of two contravariant functors
newtype Compose f g a
Compose :: f (g a) -> Compose f g a
getCompose :: Compose f g a -> f (g a)

-- | Composition of covariant and contravariant functors
newtype ComposeFC f g a
ComposeFC :: f (g a) -> ComposeFC f g a
getComposeFC :: ComposeFC f g a -> f (g a)

-- | Composition of contravariant and covariant functors
newtype ComposeCF f g a
ComposeCF :: f (g a) -> ComposeCF f g a
getComposeCF :: ComposeCF f g a -> f (g a)
instance (Divisible f, Applicative g) => Divisible (ComposeCF f g)
instance (Functor f, Functor g) => Functor (ComposeCF f g)
instance (Contravariant f, Functor g) => Contravariant (ComposeCF f g)
instance (Applicative f, Decidable g) => Decidable (ComposeFC f g)
instance (Applicative f, Divisible g) => Divisible (ComposeFC f g)
instance (Functor f, Functor g) => Functor (ComposeFC f g)
instance (Functor f, Contravariant g) => Contravariant (ComposeFC f g)
instance (Contravariant f, Contravariant g) => Functor (Compose f g)


module Data.Functor.Contravariant.Generic

-- | This provides machinery for deconstructing an arbitrary <a>Generic</a>
--   instance using a <a>Decidable</a> <a>Contravariant</a> functor.
--   
--   <i>Examples:</i>
--   
--   <pre>
--   gcompare :: <a>Deciding</a> <a>Ord</a> a =&gt; a -&gt; a -&gt; <a>Ordering</a>
--   gcompare = <a>getComparison</a> $ <a>deciding</a> (Proxy :: Proxy <a>Ord</a>) (<a>Comparison</a> <a>compare</a>)
--   </pre>
--   
--   <pre>
--   geq :: <a>Deciding</a> <a>Eq</a> a =&gt; a -&gt; a -&gt; <a>Bool</a>
--   geq = <a>getEquivalence</a> $ <a>deciding</a> (Proxy :: Proxy <a>Eq</a>) (<a>Equivalence</a> (<a>==</a>))
--   </pre>
class (Generic a, GDeciding q (Rep a)) => Deciding q a
deciding :: (Deciding q a, Decidable f) => p q -> (forall b. q b => f b) -> f a

-- | This provides machinery for deconstructing an arbitrary
--   <a>Generic1</a> instance using a <a>Decidable</a> <a>Contravariant</a>
--   functor.
--   
--   <i>Examples:</i>
--   
--   <pre>
--   gcompare1 :: <a>Deciding1</a> <a>Ord</a> f =&gt; (a -&gt; a -&gt; <a>Ordering</a>) -&gt; f a -&gt; f a -&gt; <a>Ordering</a>
--   gcompare1 f = <a>getComparison</a> $ <a>deciding1</a> (Proxy :: Proxy <a>Ord</a>) (<a>Comparison</a> compare) (<a>Comparison</a> f)
--   </pre>
--   
--   <pre>
--   geq1 :: <a>Deciding1</a> <a>Eq</a> f =&gt; (a -&gt; a -&gt; <a>Bool</a>) -&gt; f a -&gt; f a -&gt; <a>Bool</a>
--   geq1 f = <a>getEquivalence</a> $ <a>deciding1</a> (Proxy :: Proxy <a>Eq</a>) (<a>Equivalence</a> (<a>==</a>)) (<a>Equivalence</a> f)
--   </pre>
class (Generic1 t, GDeciding1 q (Rep1 t)) => Deciding1 q t
deciding1 :: (Deciding1 q t, Decidable f) => p q -> (forall b. q b => f b) -> f a -> f (t a)
instance Deciding1 q f => GDeciding1 q (Rec1 f)
instance GDeciding1 q Par1
instance GDeciding1 q f => GDeciding1 q (M1 i c f)
instance (q p) => GDeciding1 q (K1 i p)
instance (GDeciding1 q f, GDeciding1 q g) => GDeciding1 q (f :+: g)
instance (GDeciding1 q f, GDeciding1 q g) => GDeciding1 q (f :*: g)
instance GDeciding1 q V1
instance GDeciding1 q U1
instance GDeciding q f => GDeciding q (M1 i c f)
instance (q p) => GDeciding q (K1 i p)
instance (GDeciding q f, GDeciding q g) => GDeciding q (f :+: g)
instance (GDeciding q f, GDeciding q g) => GDeciding q (f :*: g)
instance GDeciding q V1
instance GDeciding q U1
instance (Generic1 t, GDeciding1 q (Rep1 t)) => Deciding1 q t
instance (Generic a, GDeciding q (Rep a)) => Deciding q a
