module Cat.Diagram.Monad.Extension where
Extension systems🔗
An extension system on a category is an alternative way of presenting a monad on As the name suggests, extension systems are built around an extension operation, of type in place of the multiplication operation that characterises a monad. This has a couple of immediate benefits:
The extension operation avoids nested applications of which tends to improve ergonomics.
The extension operation simultaneously encodes both multiplication and its underlying functorial action, which reduces the amount of data that needs to be given explicitly.
It is not immediately clear how to generalize monads beyond endofunctors. In constrast, extension systems can be readily generalized to relative extension systems1.
With that bit of motivation out of the way, we shall proceed to define extension systems. An extension system consists of:
A mapping of objects, and
A family of morphisms called the unit of the extension system; and
The extension operation, Gesturing towards the “monads” found in functional programming, we will call this operation
bind
.
Note that we do not require the mapping of objects to be functorial, nor the do we require the unit to be natural. Instead, we impose 3 equations on this structure:2
- For every we must have
- For every we must have and
- For every and we must have
For reasons of generality, we shall define extension systems as relative extension systems, along the identity functor. Even though we use a more general definition, the data contained in an extension system is precisely the data listed above.
: ∀ {o ℓ} → Precategory o ℓ → Type (o ⊔ ℓ)
Extension-system = Relative-extension-system (Id {C = C})
Extension-system C
module Extension-system {o ℓ} {C : Precategory o ℓ} (E : Extension-system C) where
open Cat.Reasoning C
open Relative-extension-system E public
We can recover the monad’s multiplication by extending the identity morphism
: ∀ {x} → Hom (M₀ (M₀ x)) (M₀ x)
join {x} = bind (id {M₀ x}) join
Naturality of join also follows, though is a bit more involved.
join-natural: ∀ {x y} (f : Hom x y)
→ join ∘ M₁ (M₁ f) ≡ M₁ f ∘ join
=
join-natural f (unit ∘ bind (unit ∘ f)) ≡⟨ bind-∘ id (unit ∘ bind (unit ∘ f)) ⟩
bind id ∘ bind (bind id ∘ unit ∘ bind (unit ∘ f)) ≡⟨ ap bind (cancell (bind-unit-∘ id) ∙ sym (idr _)) ⟩
bind (bind (unit ∘ f) ∘ id) ≡˘⟨ bind-∘ (unit ∘ f) id ⟩
bind (unit ∘ f) ∘ bind id ∎ bind
Equivalence with monads🔗
It remains to show that monads on are equivalent to extension systems on We’ll start with the forward direction. Throughout, let be a fixed monad on
: Monad C → Extension-system C
Monad→Extension-system = system where
Monad→Extension-system M module M = Monad M
open Extension-system
The mapping of objects, and the unit, are directly given by (the object part of) and by the unit natural transformation.
: Extension-system C
system .M₀ = M.M₀
system .unit = M.η _ system
Defining the extension operation is slightly trickier, but not by much. If we have a morphism then its extension is defined to be composite
.bind f = M.μ _ ∘ M.M₁ f system
Finally, a few short computations show that this definition is lawful.
.bind-unit-id =
system .μ _ ∘ M.M₁ (M.η _) ≡⟨ M.left-ident ⟩
M
id ∎.bind-unit-∘ f =
system (M.μ _ ∘ M.M₁ f) ∘ M.η _ ≡⟨ pullr (sym $ M.unit.is-natural _ _ _) ⟩
.μ _ ∘ M.η _ ∘ f ≡⟨ cancell M.right-ident ⟩
M
f ∎.bind-∘ f g =
system (M.μ _ ∘ M.M₁ f) ∘ (M.μ _ ∘ M.M₁ g) ≡⟨ pullr (extendl (sym $ M.mult.is-natural _ _ _)) ⟩
.μ _ ∘ M.μ _ ∘ (M.M₁ (M.M₁ f) ∘ M.M₁ g) ≡⟨ extendl (sym M.mult-assoc) ⟩
M.μ _ ∘ M.M₁ (M.μ _) ∘ (M.M₁ (M.M₁ f) ∘ M.M₁ g) ≡⟨ ap₂ _∘_ refl (pulll (sym (M.M-∘ _ _)) ∙ sym (M.M-∘ _ _)) ⟩
M.μ _ ∘ M.M₁ ((M.μ _ ∘ M.M₁ f) ∘ g) ∎ M
Constructing a monad from an extension system is simply a matter of bolting together our results from the previous section.
: Extension-system C → Monad C
Extension-system→Monad = monad where
Extension-system→Monad E module E = Extension-system E
open Monad
: Monad C
monad .M = E.M
monad .unit .η x = E.unit
monad .unit .is-natural _ _ f = E.unit-natural f
monad .mult .η x = E.join
monad .mult .is-natural _ _ f = E.join-natural f monad
The monad laws follow from another short series of computations.
.left-ident =
monad .bind id ∘ E.bind (E.unit ∘ E.unit) ≡⟨ E.bind-∘ _ _ ⟩
E.bind (E.bind id ∘ E.unit ∘ E.unit) ≡⟨ ap E.bind (cancell (E.bind-unit-∘ id)) ⟩
E.bind E.unit ≡⟨ E.bind-unit-id ⟩
E
id ∎.right-ident =
monad .bind id ∘ E.unit ≡⟨ E.bind-unit-∘ id ⟩
E
id ∎.mult-assoc =
monad .bind id ∘ E.bind (E.unit ∘ E.bind id) ≡⟨ E.bind-∘ _ _ ⟩
E.bind (E.bind id ∘ E.unit ∘ E.bind id) ≡⟨ ap E.bind (cancell (E.bind-unit-∘ id) ∙ sym (idr _)) ⟩
E.bind (E.bind id ∘ id) ≡˘⟨ E.bind-∘ _ _ ⟩
E.bind id ∘ E.bind id ∎ E
Moreover, these two functions constitute an equivalence between monads on and extension systems on In light of this fact, we will silently identify monads and extension systems, whenever it is convenient.
: Monad C ≃ Extension-system C
Monad≃Extension-system = Iso→Equiv $
Monad≃Extension-system
Monad→Extension-system ,
iso Extension-system→Monad(λ E →
let module E = Extension-system E in
Relative-extension-system-path(λ _ → refl)
(λ _ → refl)
(λ f →
.bind id ∘ E.bind (E.unit ∘ f i0) ≡⟨ E.bind-∘ id (E.unit ∘ f i0) ⟩
E.bind (E.bind id ∘ E.unit ∘ f i0) ≡⟨ ap E.bind (cancell (E.bind-unit-∘ id)) ⟩
E.bind (f i0) ≡⟨ ap E.bind (coe0→1 (λ i → f i0 ≡ f i) refl) ⟩
E.bind (f i1) ∎))
E(λ M →
let module M = Monad M in
Monad-path(λ _ → refl)
(λ f →
.μ _ ∘ M.M₁ (M.η _ ∘ f) ≡⟨ pushr (M.M-∘ _ _) ⟩
M(M.μ _ ∘ M.M₁ (M.η _)) ∘ M.M₁ f ≡⟨ eliml M.left-ident ⟩
.M₁ f ∎)
M(λ _ → refl)
(λ _ → elimr M.M-id))
Algebras over an extension system🔗
An extension algebra over is the extension system analog of a algebra over a monad. Following the general theme of extension operations, an extension algebra on is given by an operation Intuitively, this operation lets us “evaluate” any so long as the codomain of the evaluation is
This operation must satisfy a pair of equations:
- For every we have and
- For every and we have
As with extension systems, we define extension algebras in terms of relative extension algebras.
Extension-algebra-on: ∀ {o ℓ} {C : Precategory o ℓ}
→ (open Precategory C)
→ Extension-system C
→ Ob
→ Type (o ⊔ ℓ)
= Relative-algebra-on
Extension-algebra-on
module Extension-algebra-on
{o ℓ} {C : Precategory o ℓ} (open Cat.Reasoning C)
{E : Extension-system C} {x : Ob} (α : Extension-algebra-on E x)
where
open Extension-system E
open Relative-algebra-on α public
The evaluation map also interacts well with the multiplication.
: ∀ {a} (f : Hom a x) → ν f ∘ join ≡ ν (ν f)
ν-join =
ν-join f
ν f ∘ bind id ≡⟨ ν-bind f id ⟩(ν f ∘ id) ≡⟨ ap ν (idr _) ⟩
ν (ν f) ∎ ν
Equivalence with monad algebras🔗
As the name suggests, extension algebras over are equivalent to monad algebras over the canonical monad associated with
For the forward direction, let be a monad algebra over We can obtain the required extension operation by sending each to the composite
Algebra-on→Extension-algebra-on: ∀ {x}
→ Algebra-on C (Extension-system→Monad E) x
→ Extension-algebra-on E x
{x = x} α = ext-alg where
Algebra-on→Extension-algebra-on module α = Algebra-on α
open Extension-algebra-on
: Extension-algebra-on E x
ext-alg .ν f = α.ν ∘ M₁ f ext-alg
The monad algebra laws follow from some tedious calculations that we shall omit.
.ν-unit f =
ext-alg (α.ν ∘ M₁ f) ∘ unit ≡⟨ pullr (sym $ unit-natural f) ⟩
.ν ∘ unit ∘ f ≡⟨ cancell α.ν-unit ⟩
α
f ∎.ν-bind f g =
ext-alg (α.ν ∘ M₁ f) ∘ bind g ≡⟨ pullr (bind-naturall _ _) ⟩
.ν ∘ bind ⌜ M₁ f ∘ g ⌝ ≡⟨ ap! (insertl (bind-unit-∘ id)) ⟩
α.ν ∘ bind (join ∘ unit ∘ M₁ f ∘ g) ≡⟨ pushr (sym (bind-∘ _ _)) ⟩
α(α.ν ∘ join) ∘ bind (unit ∘ M₁ f ∘ g) ≡⟨ pushl (sym $ α.ν-mult) ⟩
.ν ∘ M₁ α.ν ∘ bind (unit ∘ M₁ f ∘ g) ≡⟨ ap (α.ν ∘_) (bind-naturall _ _) ⟩
α.ν ∘ bind ⌜ M₁ α.ν ∘ unit ∘ M₁ f ∘ g ⌝ ≡⟨ ap! (centralizel (sym $ unit-natural _)) ⟩
α.ν ∘ bind (unit ∘ (α.ν ∘ M₁ f) ∘ g) ∎ α
Conversely, a monad algebra over can be derived from an extension algebra over by restricting to
Extension-algebra-on→Algebra-on: ∀ {x}
→ Extension-algebra-on E x
→ Algebra-on C (Extension-system→Monad E) x
{x = x} α = alg where
Extension-algebra-on→Algebra-on module α = Extension-algebra-on α
open Algebra-on
: Algebra-on C (Extension-system→Monad E) x
alg .ν = α.ν id alg
The proofs of the monad algebra laws are mercifully short.
.ν-unit = α.ν-unit id
alg .ν-mult =
alg .ν id ∘ M₁ (α.ν id) ≡⟨ α.ν-natural _ _ ⟩
α.ν (id ∘ α.ν id) ≡⟨ ap α.ν (idl _) ⟩
α.ν (α.ν id) ≡˘⟨ α.ν-join id ⟩
α.ν id ∘ join ∎ α
As expected, these two functions constitute an equivalence between monad algebras and extension algebras.
Algebra-on≃Extension-algebra-on: ∀ {x}
→ Algebra-on C (Extension-system→Monad E) x ≃ Extension-algebra-on E x
{x} = Iso→Equiv $
Algebra-on≃Extension-algebra-on
Algebra-on→Extension-algebra-on ,
iso Extension-algebra-on→Algebra-on(λ α →
let module α = Extension-algebra-on α in
λ f →
Relative-algebra-on-pathp refl .ν id ∘ M₁ (f i0) ≡⟨ α.ν-natural _ _ ⟩
α.ν (id ∘ f i0) ≡⟨ ap α.ν (idl _) ⟩
α.ν (f i0) ≡⟨ ap α.ν (coe0→1 (λ i → f i0 ≡ f i) refl) ⟩
α.ν (f i1) ∎)
α(λ α →
let module α = Algebra-on α in
Algebra-on-pathp C refl $.ν ∘ bind (unit ∘ id) ≡⟨ elimr (ap bind (idr _) ∙ bind-unit-id) ⟩
α.ν ∎) α