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


-- | Categories
--   
--   Categories
@package categories
@version 1.0.6


module Control.Category.Discrete

-- | Category of discrete objects. The only arrows are identity arrows.
data Discrete a b
Refl :: Discrete a a

-- | Discrete a b acts as a proof that a = b, lift that proof into
--   something of kind * -&gt; *
liftDiscrete :: Discrete a b -> Discrete (f a) (f b)

-- | Lower the proof that a ~ b to an arbitrary category.
cast :: Category k => Discrete a b -> k a b
inverse :: Discrete a b -> Discrete b a
instance Category Discrete


-- | This module declares the <a>HasTerminalObject</a> and
--   <a>HasInitialObject</a> classes.
--   
--   These are both special cases of the idea of a (co)limit.
module Control.Categorical.Object

-- | The <tt>Category (~&gt;)</tt> has a terminal object <tt>Terminal
--   (~&gt;)</tt> such that for all objects <tt>a</tt> in <tt>(~&gt;)</tt>,
--   there exists a unique morphism from <tt>a</tt> to <tt>Terminal
--   (~&gt;)</tt>.
class Category k => HasTerminalObject k where type family Terminal k :: *
terminate :: HasTerminalObject k => a k Terminal k

-- | The <tt>Category (~&gt;)</tt> has an initial (coterminal) object
--   <tt>Initial (~&gt;)</tt> such that for all objects <tt>a</tt> in
--   <tt>(~&gt;)</tt>, there exists a unique morphism from <tt>Initial
--   (~&gt;) </tt> to <tt>a</tt>.
class Category k => HasInitialObject k where type family Initial k :: *
initiate :: HasInitialObject k => Initial k k a


module Control.Category.Dual
data Dual k a b
Dual :: k b a -> Dual k a b
runDual :: Dual k a b -> k b a
instance (Typeable2 k, Data a, Data b, Data (k b a)) => Data (Dual k a b)
instance Typeable2 k => Typeable2 (Dual k)
instance Category k => Category (Dual k)


-- | A more categorical definition of <a>Bifunctor</a>
module Control.Categorical.Bifunctor
class (Category r, Category t) => PFunctor p r t | p r -> t, p t -> r
first :: PFunctor p r t => r a b -> t (p a c) (p b c)
class (Category s, Category t) => QFunctor q s t | q s -> t, q t -> s
second :: QFunctor q s t => s a b -> t (q c a) (q c b)

-- | Minimal definition: <tt>bimap</tt>
class (PFunctor p r t, QFunctor p s t) => Bifunctor p r s t | p r -> s t, p s -> r t, p t -> r s
bimap :: Bifunctor p r s t => r a b -> s c d -> t (p a c) (p b d)
dimap :: Bifunctor f (Dual s) t u => s b a -> t c d -> u (f a c) (f b d)
difirst :: PFunctor f (Dual s) t => s b a -> t (f a c) (f b c)
instance QFunctor (->) (->) (->)
instance Bifunctor Either (->) (->) (->)
instance QFunctor Either (->) (->)
instance PFunctor Either (->) (->)
instance Bifunctor (,) (->) (->) (->)
instance QFunctor (,) (->) (->)
instance PFunctor (,) (->) (->)


-- | NB: this contradicts another common meaning for an <a>Associative</a>
--   <tt>Category</tt>, which is one where the pentagonal condition does
--   not hold, but for which there is an identity.
module Control.Category.Associative

-- | A category with an associative bifunctor satisfying Mac Lane's
--   pentagonal coherence identity law:
--   
--   <pre>
--   bimap id associate . associate . bimap associate id = associate . associate
--   bimap disassociate id . disassociate . bimap id disassociate = disassociate . disassociate
--   </pre>
class Bifunctor p k k k => Associative k p
associate :: Associative k p => k (p (p a b) c) (p a (p b c))
disassociate :: Associative k p => k (p a (p b c)) (p (p a b) c)
instance Associative (->) Either
instance Associative (->) (,)


-- | A <a>Monoidal</a> category is a category with an associated
--   biendofunctor that has an identity, which satisfies Mac Lane''s
--   pentagonal and triangular coherence conditions Technically we usually
--   say that category is <a>Monoidal</a>, but since most interesting
--   categories in our world have multiple candidate bifunctors that you
--   can use to enrich their structure, we choose here to think of the
--   bifunctor as being monoidal. This lets us reuse the same
--   <tt>Bifunctor</tt> over different categories without painful newtype
--   wrapping.
module Control.Category.Monoidal

-- | Denotes that we have some reasonable notion of <tt>Identity</tt> for a
--   particular <tt>Bifunctor</tt> in this <tt>Category</tt>. This notion
--   is currently used by both <a>Monoidal</a> and <tt>Comonoidal</tt>
--   
--   A monoidal category. <a>idl</a> and <a>idr</a> are traditionally
--   denoted lambda and rho the triangle identities hold:
--   
--   <pre>
--   first idr = second idl . associate
--   second idl = first idr . associate
--   first idr = disassociate . second idl
--   second idl = disassociate . first idr
--   idr . coidr = id
--   idl . coidl = id
--   coidl . idl = id
--   coidr . idr = id
--   </pre>
class Associative k p => Monoidal (k :: * -> * -> *) (p :: * -> * -> *) where type family Id (k :: * -> * -> *) (p :: * -> * -> *) :: *
idl :: Monoidal k p => k (p (Id k p) a) a
idr :: Monoidal k p => k (p a (Id k p)) a
coidl :: Monoidal k p => k a (p (Id k p) a)
coidr :: Monoidal k p => k a (p a (Id k p))
instance Monoidal (->) Either
instance Monoidal (->) (,)


module Control.Category.Braided

-- | A braided (co)(monoidal or associative) category can commute the
--   arguments of its bi-endofunctor. Obeys the laws:
--   
--   <pre>
--   associate . braid . associate = second braid . associate . first braid
--   disassociate . braid . disassociate = first braid . disassociate . second braid
--   </pre>
--   
--   If the category is Monoidal the following laws should be satisfied
--   
--   <pre>
--   idr . braid = idl
--   idl . braid = idr
--   </pre>
--   
--   If the category is Comonoidal the following laws should be satisfied
--   
--   <pre>
--   braid . coidr = coidl
--   braid . coidl = coidr
--   </pre>
class Associative k p => Braided k p
braid :: Braided k p => k (p a b) (p b a)

-- | If we have a symmetric (co)<tt>Monoidal</tt> category, you get the
--   additional law:
--   
--   <pre>
--   swap . swap = id
--   </pre>
class Braided k p => Symmetric k p
swap :: Symmetric k p => k (p a b) (p b a)
instance Symmetric (->) (,)
instance Symmetric (->) Either
instance Braided (->) (,)
instance Braided (->) Either


module Control.Category.Cartesian

-- | Minimum definition:
--   
--   <pre>
--   fst, snd, diag
--   fst, snd, (&amp;&amp;&amp;)
--   </pre>
class (Symmetric k (Product k), Monoidal k (Product k)) => Cartesian k where type family Product k :: * -> * -> * diag = id &&& id f &&& g = bimap f g . diag
fst :: Cartesian k => Product k a b k a
snd :: Cartesian k => Product k a b k b
diag :: Cartesian k => a k Product k a a
(&&&) :: Cartesian k => (a k b) -> (a k c) -> a k Product k b c

-- | free construction of <a>Bifunctor</a> for the product <a>Bifunctor</a>
--   <tt>Product k</tt> if <tt>(&amp;&amp;&amp;)</tt> is known
bimapProduct :: Cartesian k => k a c -> k b d -> Product k a b k Product k c d

-- | free construction of <a>Braided</a> for the product <a>Bifunctor</a>
--   <tt>Product k</tt>
braidProduct :: Cartesian k => k (Product k a b) (Product k b a)

-- | free construction of <tt>Associative</tt> for the product
--   <a>Bifunctor</a> <tt>Product k</tt>
associateProduct :: Cartesian k => Product k (Product k a b) c k Product k a (Product k b c)

-- | free construction of <tt>Disassociative</tt> for the product
--   <a>Bifunctor</a> <tt>Product k</tt>
disassociateProduct :: Cartesian k => Product k a (Product k b c) k Product k (Product k a b) c
class (Monoidal k (Sum k), Symmetric k (Sum k)) => CoCartesian k where type family Sum k :: * -> * -> * codiag = id ||| id f ||| g = codiag . bimap f g
inl :: CoCartesian k => a k Sum k a b
inr :: CoCartesian k => b k Sum k a b
codiag :: CoCartesian k => Sum k a a k a
(|||) :: CoCartesian k => k a c -> k b c -> Sum k a b k c

-- | free construction of <a>Bifunctor</a> for the coproduct
--   <a>Bifunctor</a> <tt>Sum k</tt> if <tt>(|||)</tt> is known
bimapSum :: CoCartesian k => k a c -> k b d -> Sum k a b k Sum k c d

-- | free construction of <a>Braided</a> for the coproduct <a>Bifunctor</a>
--   <tt>Sum k</tt>
braidSum :: CoCartesian k => Sum k a b k Sum k b a

-- | free construction of <tt>Associative</tt> for the coproduct
--   <a>Bifunctor</a> <tt>Sum k</tt>
associateSum :: CoCartesian k => Sum k (Sum k a b) c k Sum k a (Sum k b c)

-- | free construction of <tt>Disassociative</tt> for the coproduct
--   <a>Bifunctor</a> <tt>Sum k</tt>
disassociateSum :: CoCartesian k => Sum k a (Sum k b c) k Sum k (Sum k a b) c
instance CoCartesian (->)
instance Cartesian (->)


module Control.Category.Cartesian.Closed

-- | A <a>CCC</a> has full-fledged monoidal finite products and
--   exponentials
class Cartesian k => CCC k where type family Exp k :: * -> * -> *
apply :: CCC k => Product k (Exp k a b) a k b
curry :: CCC k => Product k a b k c -> a k Exp k b c
uncurry :: CCC k => a k Exp k b c -> Product k a b k c
unitCCC :: CCC k => a k Exp k b (Product k b a)
counitCCC :: CCC k => Product k b (Exp k b a) k a

-- | A Co-CCC has full-fledged comonoidal finite coproducts and
--   coexponentials
class CoCartesian k => CoCCC k where type family Coexp k :: * -> * -> *
coapply :: CoCCC k => b k Sum k (Coexp k a b) a
cocurry :: CoCCC k => c k Sum k a b -> Coexp k b c k a
uncocurry :: CoCCC k => Coexp k b c k a -> c k Sum k a b
unitCoCCC :: CoCCC k => a k Sum k b (Coexp k b a)
counitCoCCC :: CoCCC k => Coexp k b (Sum k b a) k a
instance CCC (->)


module Control.Category.Distributive

-- | The canonical factoring morphism.
factor :: (Cartesian k, CoCartesian k) => Sum k (Product k a b) (Product k a c) k Product k a (Sum k b c)

-- | A category in which <a>factor</a> is an isomorphism
class (Cartesian k, CoCartesian k) => Distributive k
distribute :: Distributive k => Product k a (Sum k b c) k Sum k (Product k a b) (Product k a c)
instance Distributive (->)


-- | A more categorical definition of <a>Functor</a>
module Control.Categorical.Functor
class (Category r, Category t) => Functor f r t | f r -> t, f t -> r
fmap :: Functor f r t => r a b -> t (f a) (f b)
class Functor f a a => Endofunctor f a
newtype LiftedFunctor f a
LiftedFunctor :: (f a) -> LiftedFunctor f a
newtype LoweredFunctor f a
LoweredFunctor :: (f a) -> LoweredFunctor f a
instance Show (f a) => Show (LiftedFunctor f a)
instance Read (f a) => Read (LiftedFunctor f a)
instance Show (f a) => Show (LoweredFunctor f a)
instance Read (f a) => Read (LoweredFunctor f a)
instance Functor f a a => Endofunctor f a
instance Functor IO (->) (->)
instance Functor [] (->) (->)
instance Functor Maybe (->) (->)
instance Functor (Either a) (->) (->)
instance Functor ((,) a) (->) (->)
instance Functor f => Functor (LiftedFunctor f) (->) (->)
instance Functor f (->) (->) => Functor (LoweredFunctor f)
instance (Typeable1 f, Data (f a), Data a) => Data (LoweredFunctor f a)
instance Typeable1 f => Typeable1 (LoweredFunctor f)
instance (Typeable1 f, Data (f a), Data a) => Data (LiftedFunctor f a)
instance Typeable1 f => Typeable1 (LiftedFunctor f)
