module Cat.Diagram.Monad where
Monadsπ
A monad on a category
is one way of categorifying the concept of monoid. Specifically, rather than living
in a monoidal category, a monad lives in a bicategory. Here, we concern
ourselves with the case of monads in the bicategory of categories, so
that we may say: A monad is an endofunctor
equipped with a unit
natural transformation
and a multiplication
record Monad : Type (o β h) where no-eta-equality field M : Functor C C unit : Id => M mult : (M Fβ M) => M
module unit = _=>_ unit module mult = _=>_ mult Mβ = M .Fβ Mβ = M .Fβ M-id = M .F-id M-β = M .F-β open unit using (Ξ·) public open mult renaming (Ξ· to ΞΌ) using () public
Furthermore, these natural transformations must satisfy identity and associativity laws exactly analogous to those of a monoid.
field left-ident : β {x} β ΞΌ x C.β Mβ (Ξ· x) β‘ C.id right-ident : β {x} β ΞΌ x C.β Ξ· (Mβ x) β‘ C.id mult-assoc : β {x} β ΞΌ x C.β Mβ (ΞΌ x) β‘ ΞΌ x C.β ΞΌ (Mβ x)
Algebras over a monadπ
One way of interpreting a monad is as giving a signature for an algebraic theory. For instance, the free monoid monad describes the signature for the theory of monoids, and the free group monad describes the theory of groups.
Under this light, an algebra over a monad is a way of evaluating the abstract operations given by a monadic expression to a concrete value. Formally, an algebra for is given by a choice of object and a morphism
record Algebra-on (M : Monad) (ob : C.Ob) : Type (o β h) where no-eta-equality open Monad M field Ξ½ : C.Hom (Mβ ob) ob
This morphism must satisfy equations categorifying those which define
a monoid action. If we think of
as specifying a signature of effects, then v-unit
says that the unit
has no effects, and v-mult
says that, given two layers
it doesnβt matter whether you first join then evaluate, or evaluate
twice.
Ξ½-unit : Ξ½ C.β Ξ· ob β‘ C.id Ξ½-mult : Ξ½ C.β Mβ Ξ½ β‘ Ξ½ C.β ΞΌ ob Algebra : Monad β Type (o β h) Algebra M = Ξ£ _ (Algebra-on M)
Algebra-on-pathp : β {M} {X Y} (p : X β‘ Y) {A : Algebra-on M X} {B : Algebra-on M Y} β PathP (Ξ» i β C.Hom (Monad.Mβ M (p i)) (p i)) (A .Algebra-on.Ξ½) (B .Algebra-on.Ξ½) β PathP (Ξ» i β Algebra-on M (p i)) A B Algebra-on-pathp over mults i .Algebra-on.Ξ½ = mults i Algebra-on-pathp {M} over {A} {B} mults i .Algebra-on.Ξ½-unit = is-propβpathp (Ξ» i β C.Hom-set _ _ (mults i C.β M.Ξ· _) (C.id {x = over i})) (A .Algebra-on.Ξ½-unit) (B .Algebra-on.Ξ½-unit) i where module M = Monad M Algebra-on-pathp {M} over {A} {B} mults i .Algebra-on.Ξ½-mult = is-propβpathp (Ξ» i β C.Hom-set _ _ (mults i C.β M.Mβ (mults i)) (mults i C.β M.ΞΌ _)) (A .Algebra-on.Ξ½-mult) (B .Algebra-on.Ξ½-mult) i where module M = Monad M
Eilenberg-Moore categoryπ
If we take a monad
as the signature of an (algebraic) theory, and
as giving models of that theory, then we can ask (like with
everything in category theory): Are there maps between interpretations?
The answer (as always!) is yes: An algebra homomorphism
is a map of
the underlying objects which βcommutes with the algebrasβ.
record Algebra-hom (M : Monad) (X Y : Algebra M) : Type (o β h) where no-eta-equality constructor algebra-hom private module X = Algebra-on (X .snd) module Y = Algebra-on (Y .snd) open Monad M field morphism : C.Hom (X .fst) (Y .fst) commutes : morphism C.β X.Ξ½ β‘ Y.Ξ½ C.β Mβ morphism open Algebra-hom
We can be more specific about βcommuting with the algebrasβ by drawing a square: A map in the ambient category is a homomorphism of when the square below commutes.
Since commutes
is an identification
between morphisms, it inhabits a proposition (because Hom-sets are sets
), equality of
algebra homomorphisms only depends on an equality of their underlying
morphisms.
Algebra-hom-path : {M : Monad} {X Y : Algebra M} {F G : Algebra-hom M X Y} β morphism F β‘ morphism G β F β‘ G Algebra-hom-path x i .morphism = x i Algebra-hom-path {M = M} {X} {Y} {F} {G} x i .commutes = is-propβpathp (Ξ» i β C.Hom-set _ _ (x i C.β X .snd .Algebra-on.Ξ½) (Y .snd .Algebra-on.Ξ½ C.β Monad.Mβ M (x i))) (F .commutes) (G .commutes) i
Algebra-hom-pathp : {M : Monad} {W X Y Z : Algebra M} {F : Algebra-hom M W X} {G : Algebra-hom M Y Z} (p : W β‘ Y) (q : X β‘ Z) β PathP _ (morphism F) (morphism G) β PathP (Ξ» i β Algebra-hom M (p i) (q i)) F G Algebra-hom-pathp p q r i .morphism = r i Algebra-hom-pathp {M = M} {W} {X} {Y} {Z} {F} {G} p q r i .commutes = is-propβpathp (Ξ» i β C.Hom-set _ _ (r i C.β p i .snd .Algebra-on.Ξ½) (q i .snd .Algebra-on.Ξ½ C.β Monad.Mβ M (r i))) (F .commutes) (G .commutes) i
open Algebra-hom public open _=>_ using (Ξ·) module _ {o β} {C : Precategory o β} {M : Monad C} where instance private module C = Cat.Reasoning C Extensional-Algebra-Hom : β {βr} {a b} {A : Algebra-on C M a} {B : Algebra-on C M b} β β¦ sa : Extensional (C.Hom a b) βr β¦ β Extensional (Algebra-hom C M (a , A) (b , B)) βr Extensional-Algebra-Hom β¦ sa β¦ = injectionβextensional! (Algebra-hom-path C) sa Funlike-Algebra-hom : β {β β'} {A : Type β} {B : A β Type β'} {X Y} β β¦ i : Funlike (C.Hom (X .fst) (Y .fst)) A B β¦ β Funlike (Algebra-hom C M X Y) A B Funlike-Algebra-hom β¦ i β¦ .Funlike._#_ f x = f .morphism # x unquoteDecl H-Level-Algebra-hom = declare-record-hlevel 2 H-Level-Algebra-hom (quote Algebra-hom) module _ {o β} (C : Precategory o β) where private module C = Cat.Reasoning C
Since the square we drew above commutes for the identity morphism, and we can show that the composite of two algebra homomorphisms is an algebra homomorphism, they assemble into a category: The Eilenberg-Moore category of
module _ (M : Monad C) where private module M = Monad M open M hiding (M) open Precategory open Algebra-on Eilenberg-Moore : Precategory _ _ Eilenberg-Moore .Ob = Algebra C M Eilenberg-Moore .Hom X Y = Algebra-hom C M X Y
Defining the identity and composition maps is mostly an exercise in categorical yoga:
Eilenberg-Moore .id {o , x} .morphism = C.id Eilenberg-Moore .id {o , x} .commutes = C.id C.β Ξ½ x β‘β¨ C.id-comm-sym β©β‘ Ξ½ x C.β C.id β‘β¨ ap (C._β_ _) (sym M-id) β©β‘ Ξ½ x C.β Mβ C.id β Eilenberg-Moore ._β_ {_ , x} {_ , y} {_ , z} F G .morphism = morphism F C.β morphism G Eilenberg-Moore ._β_ {_ , x} {_ , y} {_ , z} F G .commutes = (morphism F C.β morphism G) C.β Ξ½ x β‘β¨ C.extendr (commutes G) β©β‘ β morphism F C.β Ξ½ y β C.β Mβ (morphism G) β‘β¨ ap! (commutes F) β©β‘ (Ξ½ z C.β Mβ (morphism F)) C.β Mβ (morphism G) β‘β¨ C.pullr (sym (M-β _ _)) β©β‘ Ξ½ z C.β Mβ (morphism F C.β morphism G) β
Because we have characterised equality of algebra homomorphisms as equality of their underlying maps, the Eilenberg-Moore category inherits the identity and associativity laws from its underlying category.
Eilenberg-Moore .idr f = ext (C.idr _) Eilenberg-Moore .idl f = ext (C.idl _) Eilenberg-Moore .assoc f g h = ext (C.assoc _ _ _) Eilenberg-Moore .Hom-set X Y = hlevel 2
By projecting the underlying object of the algebras, and the
underlying morphisms of the homomorphisms between them, we can define a
functor from Eilenberg-Moore
back to the
underlying category:
Forget : Functor Eilenberg-Moore C Forget .Fβ = fst Forget .Fβ = Algebra-hom.morphism Forget .F-id = refl Forget .F-β f g = refl
The lemma Algebra-hom-path
says exactly
that this functor is faithful.
Forget-is-faithful : is-faithful Forget Forget-is-faithful = ext
Free algebrasπ
In exactly the same way that we may construct a free group by taking the inhabitants of some set as generating the βwordsβ of a group, we can, given an object of the underlying category, build a free on Keeping with our interpretation of monads as logical signatures, this is the syntactic model of with a set of βneutralsβ chosen from the object
This construction is a lot simpler to do in generality than in any specific case: We can always turn into an by taking the underlying object to be and the algebra map to be the monadic multiplication; The associativity and unit laws of the monad itself become those of the
Free : Functor C Eilenberg-Moore Free .Fβ A .fst = Mβ A Free .Fβ A .snd .Ξ½ = mult .Ξ· A Free .Fβ A .snd .Ξ½-mult = mult-assoc Free .Fβ A .snd .Ξ½-unit = right-ident
The construction of free is furthermore functorial on the underlying objects; Since the monadic multiplication is a natural transformation the naturality condition (drawn below) doubles as showing that the functorial action of can be taken as an algebraic action:
Free .Fβ f .morphism = Mβ f Free .Fβ f .commutes = sym $ mult.is-natural _ _ _ Free .F-id = ext M-id Free .F-β f g = ext (M-β f g)
This is a free construction in the precise sense of the word: itβs
the left adjoint to the functor
Forget
, so in particular it
provides a systematic, universal way of
mapping from
to
open _β£_ Freeβ£Forget : Free β£ Forget Freeβ£Forget .unit = NT M.Ξ· M.unit.is-natural Freeβ£Forget .counit .Ξ· x = record { morphism = x .snd .Ξ½ ; commutes = sym (x .snd .Ξ½-mult) } Freeβ£Forget .counit .is-natural x y f = ext (sym (commutes f)) Freeβ£Forget .zig = ext left-ident Freeβ£Forget .zag {x} = x .snd .Ξ½-unit
module _ {o h : _} {C : Precategory o h} {M N : Monad C} where private module C = Cat.Reasoning C module M = Monad M module N = Monad N Monad-path : (p0 : β x β M.Mβ x β‘ N.Mβ x) β (p1 : β {x y} (f : C.Hom x y) β PathP (Ξ» i β C.Hom (p0 x i) (p0 y i)) (M.Mβ f) (N.Mβ f)) β (β x β PathP (Ξ» i β C.Hom x (p0 x i)) (M.Ξ· x) (N.Ξ· x)) β (β x β PathP (Ξ» i β C.Hom (p0 (p0 x i) i) (p0 x i)) (M.ΞΌ x) (N.ΞΌ x)) β M β‘ N Monad-path p0 p1 punit pmult = path where M=N : M.M β‘ N.M M=N = Functor-path p0 p1 path : M β‘ N path i .Monad.M = M=N i path i .Monad.unit = Nat-pathp refl M=N {a = M.unit} {b = N.unit} punit i path i .Monad.mult = Nat-pathp (apβ _Fβ_ M=N M=N) M=N {a = M.mult} {b = N.mult} pmult i path i .Monad.left-ident {x = x} = is-propβpathp (Ξ» i β C.Hom-set (p0 x i) (p0 x i) (pmult x i C.β p1 (punit x i) i) C.id) M.left-ident N.left-ident i path i .Monad.right-ident {x = x} = is-propβpathp (Ξ» i β C.Hom-set (p0 x i) (p0 x i) (pmult x i C.β punit (p0 x i) i) C.id) M.right-ident N.right-ident i path i .Monad.mult-assoc {x} = is-propβpathp (Ξ» i β C.Hom-set (p0 (p0 (p0 x i) i) i) (p0 x i) (pmult x i C.β p1 (pmult x i) i) (pmult x i C.β pmult (p0 x i) i)) M.mult-assoc N.mult-assoc i