Bifunctors
Using the product of categories we can define Bifunctors a functor using a product of categories in the codomain.
Bifunctor : Type
Bifunctor = (c1 × c2) ->> c3Given a functor and we can apply to and obtain a functor .
public export
applyBifunctor : {0 o1, o2, o3 : Type} ->
{a : Category o1} ->
{0 b : Category o2} ->
{0 c : Category o3} ->
o1 -> Bifunctor a b c -> b ->> c
applyBifunctor x mult = MkFunctor
(curry mult.mapObj x)
(\k, l, m => mult.mapHom (x && k) (x && l) (a.id x && m))
(\v => mult.presId (x && v) )
(\ax, bx, cx, f, g =>
cong (mult .mapHom (x && ?) (x && ?)) (
cong (&& (|:>) b f g) (sym (a.idLeft _ _ (a.id x)))) `trans`
mult.presComp (x && ax) (x && bx) (x && cx) (a.id x && f) (a.id x && g))
public export
applyBifunctor' : {0 a : Category o} -> {b : Category o} -> o -> Bifunctor a b c -> a ->> c
applyBifunctor' x mult = MkFunctor
(\y => mult.mapObj (y && x))
(\k, l, m => mult.mapHom (k && x) (l && x) (m && b.id x))
(\v => mult.presId (v && x))
(\ax, bx, cx, f, g =>
(cong (mult .mapHom (? && x) (? && x))
$ cong ((|:>) a f g &&)
$ sym $ b.idRight _ _ $ b.id x) `trans`
mult.presComp (ax && x) (bx && x) (cx && x) (f && b.id x) (g && b.id x))We can relate our notion of categorical products with the product of categories by stating that given a category with products, we can define a functor that maps each objects to using its product, and the product’s universal property to combine morphisms.
public export
ProductFunctor : {c : Category o} -> HasProduct c -> Bifunctor c c c
ProductFunctor (MkProd pair pi1 pi2 prod prodLeft prodRight uniq) = MkFunctor
(uncurry pair)
(\_, _, (m1 && m2) => prod ((|:>) c pi1 m1)
((|:>) c pi2 m2))
-- proofs in appendixpublic export 0
Bendo : Category o -> Type
Bendo c = c × c ->> c