{-# OPTIONS --without-K --safe #-}
module Categories.Monad.Construction.Kleisli where
open import Level
open import Categories.Category.Core using (Category)
open import Categories.Monad.Relative using (RMonad⇒Functor) renaming (Monad to RMonad)
open import Categories.Monad using (Monad)
open import Categories.Functor using (Functor; Endofunctor; _∘F_) renaming (id to idF)
open import Categories.NaturalTransformation using (ntHelper; NaturalTransformation)
import Categories.Morphism.Reasoning as MR
private
variable
o ℓ e : Level
module _ (C : Category o ℓ e) where
open Category C
open HomReasoning
open Equiv
open MR C
KleisliTriple : Set (o ⊔ ℓ ⊔ e)
KleisliTriple = RMonad {C = C} idF
Kleisli⇒Monad : KleisliTriple → Monad C
Kleisli⇒Monad K = record
{ F = F
; η = η
; μ = μ
; assoc = assoc'
; sym-assoc = sym assoc'
; identityˡ = identityˡ'
; identityʳ = K.identityʳ
}
where
module K = RMonad K
open K using (unit; extend)
F : Endofunctor C
F = RMonad⇒Functor K
open Functor F using (F₀; F₁)
η = ntHelper {F = idF} {G = F} record
{ η = λ X → unit
; commute = λ f → sym K.identityʳ
}
commute' : ∀ {X Y : Obj } (f : X ⇒ F₀ Y) → extend id ∘ extend (unit ∘ extend f) ≈ extend f ∘ (extend id)
commute' {X} {Y} f = begin
extend id ∘ extend (unit ∘ extend f) ≈⟨ K.sym-assoc ⟩
extend (extend id ∘ unit ∘ extend f) ≈⟨ K.extend-≈ (pullˡ K.identityʳ) ⟩
extend (id ∘ extend f) ≈⟨ K.extend-≈ id-comm-sym ⟩
extend (extend f ∘ id) ≈⟨ K.assoc ⟩
extend f ∘ (extend id) ∎
μ = ntHelper {F = F ∘F F} {G = F} record
{ η = λ X → extend id
; commute = λ f → commute' (unit ∘ f)
}
module η = NaturalTransformation η
module μ = NaturalTransformation μ
assoc' : ∀ {X : Obj} → μ.η X ∘ F₁ (μ.η X) ≈ μ.η X ∘ μ.η (F₀ X)
assoc' = commute' id
identityˡ' : ∀ {X : Obj} → μ.η X ∘ F₁ (η.η X) ≈ id
identityˡ' = begin
extend id ∘ extend (unit ∘ unit) ≈⟨ K.sym-assoc ⟩
extend (extend id ∘ (unit ∘ unit)) ≈⟨ K.extend-≈ (pullˡ K.identityʳ) ⟩
extend (id ∘ unit) ≈⟨ K.extend-≈ identityˡ ⟩
extend unit ≈⟨ K.identityˡ ⟩
id ∎
Monad⇒Kleisli : Monad C → KleisliTriple
Monad⇒Kleisli M = record
{ F₀ = F₀
; unit = η.η _
; extend = λ f → μ.η _ ∘ F₁ f
; identityʳ = identityʳ'
; identityˡ = M.identityˡ
; assoc = assoc'
; sym-assoc = sym assoc'
; extend-≈ = λ fg → ∘-resp-≈ʳ (F-resp-≈ fg)
}
where
module M = Monad M
open Monad M using (F; η; μ)
open Functor F
identityʳ' : ∀ {X Y} {k : X ⇒ F₀ Y} → (μ.η Y ∘ F₁ k) ∘ η.η X ≈ k
identityʳ' {X} {Y} {k} = begin
((μ.η Y ∘ F₁ k) ∘ η.η X) ≈⟨ pullʳ (sym (η.commute _)) ⟩
(μ.η Y ∘ η.η (F₀ Y) ∘ k) ≈⟨ cancelˡ M.identityʳ ⟩
k ∎
assoc' : ∀ {X Y Z} {k : X ⇒ F₀ Y} {l : Y ⇒ F₀ Z} → μ.η Z ∘ F₁ ((μ.η Z ∘ F₁ l) ∘ k) ≈ (μ.η Z ∘ F₁ l) ∘ μ.η Y ∘ F₁ k
assoc' {X} {Y} {Z} {k} {l} = begin
(μ.η Z ∘ F₁ ((μ.η Z ∘ F₁ l) ∘ k)) ≈⟨ refl⟩∘⟨ homomorphism ⟩
(μ.η Z ∘ F₁ (μ.η Z ∘ ₁ l) ∘ F₁ k) ≈⟨ refl⟩∘⟨ homomorphism ⟩∘⟨refl ⟩
(μ.η Z ∘ (F₁ (μ.η Z) ∘ F₁ (F₁ l)) ∘ F₁ k) ≈⟨ pullˡ (pullˡ M.assoc) ⟩
(((μ.η Z ∘ μ.η (F₀ Z)) ∘ F₁ (F₁ l)) ∘ F₁ k) ≈⟨ pullʳ (μ.commute l) ⟩∘⟨refl ⟩
(μ.η Z ∘ F₁ l ∘ μ.η Y) ∘ F₁ k ≈⟨ assoc²βγ ⟩
(μ.η Z ∘ F₁ l) ∘ μ.η Y ∘ F₁ k ∎