module NatTr.Coproduct where import Data.Constraint hiding ((&&&)) import Data.Tagged import Data.Proxy import Adjoint import Category import Category.Product import Functor import Functor.Product import Product import Coproduct import NatTr instance (Category c1, CoproductCategory c2) => Functor (CoproductF (NatTr c1 (c2 :: o2 -> o2 -> *))) ('KProxy :: KProxy ((*, *) -> *)) where type Domain (CoproductF (NatTr c1 c2)) = NatTr c1 c2 :><: NatTr c1 c2 type Codomain (CoproductF (NatTr c1 c2)) = NatTr c1 c2 type FMap (CoproductF (NatTr c1 c2)) '((f :: *), (g :: *)) = Comp ('KProxy :: KProxy (o2, o2)) (CoproductF c2) (f :&&&: g) morphMap = (Tagged (\t@(f :><: g) -> case observeObjects t of Dict -> coproduct (appNat inj1 . f) (appNat inj2 . g))) instance (Category c1, CoproductCategory c2) => Adjoint (NatTr c1 c2 :><: NatTr c1 c2) (NatTr (c1 :: o1 -> o1 -> *) (c2 :: o2 -> o2 -> *)) (CoproductF (NatTr c1 c2)) (Diag (NatTr c1 c2)) where leftAdjunct = NatTr (Tagged (\t -> (t . compFR inj1 . proj1FInv) :><: (t . compFR inj2 . proj2FInv))) rightAdjunct = NatTr (Tagged (\(t1 :><: t2) -> idL . compFR counit . assocL . compFL (diagInv . productNat t1 t2))) instance (Category c1, CoproductCategory c2) => CoproductCategory (NatTr c1 c2) type f :+: g = Coproduct (NatTr (->) (->)) f g