module Control.Category.Cartesian
(
PreCartesian(..)
, bimapProduct, braidProduct, associateProduct, disassociateProduct
, PreCoCartesian(..)
, bimapSum, braidSum, associateSum, disassociateSum
, Cartesian
, CoCartesian
) where
import Control.Category.Associative
import Control.Category.Braided
import Control.Category.Monoidal
import Prelude hiding (Functor, map, (.), id, fst, snd, curry, uncurry)
import qualified Prelude (fst,snd)
import Control.Categorical.Bifunctor
import Control.Category
infixr 3 &&&
infixr 2 |||
class ( Associative (~>) (Product (~>))
, Disassociative (~>) (Product (~>))
, Symmetric (~>) (Product (~>))
, Braided (~>) (Product (~>))
) => PreCartesian (~>) where
type Product (~>) :: * -> * -> *
fst :: Product (~>) a b ~> a
snd :: Product (~>) a b ~> b
diag :: a ~> Product (~>) a a
(&&&) :: (a ~> b) -> (a ~> c) -> a ~> Product (~>) b c
diag = id &&& id
f &&& g = bimap f g . diag
instance PreCartesian (->) where
type Product (->) = (,)
fst = Prelude.fst
snd = Prelude.snd
diag a = (a,a)
(f &&& g) a = (f a, g a)
class ( Monoidal (~>) (Product (~>))
, PreCartesian (~>)
) => Cartesian (~>)
instance ( Monoidal (~>) (Product (~>))
, PreCartesian (~>)
) => Cartesian (~>)
bimapProduct :: (PreCartesian (~>), (<*>) ~ Product (~>)) => (a ~> c) -> (b ~> d) -> (a <*> b) ~> (c <*> d)
bimapProduct f g = (f . fst) &&& (g . snd)
braidProduct :: (PreCartesian (~>)) => Product (~>) a b ~> Product (~>) b a
braidProduct = snd &&& fst
associateProduct :: (PreCartesian (~>)) => Product (~>) (Product (~>) a b) c ~> Product (~>) a (Product (~>) b c)
associateProduct = (fst . fst) &&& first snd
disassociateProduct:: (PreCartesian (~>)) => Product (~>) a (Product (~>) b c) ~> Product (~>) (Product (~>) a b) c
disassociateProduct= braid . second braid . associateProduct . first braid . braid
class ( Associative (~>) (Sum (~>))
, Disassociative (~>) (Sum (~>))
, Symmetric (~>) (Product (~>))
, Braided (~>) (Sum (~>))
) => PreCoCartesian (~>) where
type Sum (~>) :: * -> * -> *
inl :: a ~> Sum (~>) a b
inr :: b ~> Sum (~>) a b
codiag :: Sum (~>) a a ~> a
(|||) :: (a ~> c) -> (b ~> c) -> Sum (~>) a b ~> c
codiag = id ||| id
f ||| g = codiag . bimap f g
instance PreCoCartesian (->) where
type Sum (->) = Either
inl = Left
inr = Right
codiag (Left a) = a
codiag (Right a) = a
(f ||| _) (Left a) = f a
(_ ||| g) (Right a) = g a
bimapSum :: (PreCoCartesian (~>), Sum (~>) ~ (+)) => (a ~> c) -> (b ~> d) -> (a + b) ~> (c + d)
bimapSum f g = (inl . f) ||| (inr . g)
braidSum :: (PreCoCartesian (~>), (+) ~ Sum (~>)) => (a + b) ~> (b + a)
braidSum = inr ||| inl
associateSum :: (PreCoCartesian (~>)) => Sum (~>) (Sum (~>) a b) c ~> Sum (~>) a (Sum (~>) b c)
associateSum = braid . first braid . disassociateSum . second braid . braid
disassociateSum :: (PreCoCartesian (~>)) => Sum (~>) a (Sum (~>) b c) ~> Sum (~>) (Sum (~>) a b) c
disassociateSum = (inl . inl) ||| first inr
class
( Comonoidal (~>) (Sum (~>))
, PreCoCartesian (~>)
) => CoCartesian (~>)
instance
( Comonoidal (~>) (Sum (~>))
, PreCoCartesian (~>)
) => CoCartesian (~>)