{-# OPTIONS --without-K --safe #-} open import Categories.Category.Core using (Category) open import Categories.Monad using (Monad) module Categories.Adjoint.Construction.Kleisli {o ℓ e} {C : Category o ℓ e} (M : Monad C) where open import Categories.Category.Construction.Kleisli using (Kleisli) open import Categories.Adjoint using (_⊣_) open import Categories.Functor using (Functor; _∘F_) open import Categories.Morphism using (Iso) open import Categories.Functor.Properties using ([_]-resp-square) open import Categories.NaturalTransformation.Core using (ntHelper) open import Categories.NaturalTransformation.NaturalIsomorphism using (_≃_) open import Categories.Morphism.Reasoning C private module C = Category C module M = Monad M open M.F open M using (module μ; module η) open C using (Obj; _⇒_; _∘_; _≈_; ∘-resp-≈ʳ; ∘-resp-≈ˡ; assoc; sym-assoc; identityˡ) open C.HomReasoning open C.Equiv Forgetful : Functor (Kleisli M) C Forgetful = record { F₀ = λ X → F₀ X ; F₁ = λ f → μ.η _ ∘ F₁ f ; identity = M.identityˡ ; homomorphism = λ {X Y Z} {f g} → begin μ.η Z ∘ F₁ ((μ.η Z ∘ F₁ g) ∘ f) ≈⟨ refl⟩∘⟨ homomorphism ⟩ μ.η Z ∘ F₁ (μ.η Z ∘ F₁ g) ∘ F₁ f ≈⟨ refl⟩∘⟨ homomorphism ⟩∘⟨refl ⟩ μ.η Z ∘ (F₁ (μ.η Z) ∘ F₁ (F₁ g)) ∘ F₁ f ≈⟨ pull-first M.assoc ⟩ (μ.η Z ∘ μ.η (F₀ Z)) ∘ F₁ (F₁ g) ∘ F₁ f ≈⟨ center (μ.commute g) ⟩ μ.η Z ∘ (F₁ g ∘ μ.η Y) ∘ F₁ f ≈⟨ pull-first refl ⟩ (μ.η Z ∘ F₁ g) ∘ μ.η Y ∘ F₁ f ∎ ; F-resp-≈ = λ eq → ∘-resp-≈ʳ (F-resp-≈ eq) } Free : Functor C (Kleisli M) Free = record { F₀ = λ X → X ; F₁ = λ f → η.η _ ∘ f ; identity = C.identityʳ ; homomorphism = λ {X Y Z} {f g} → begin η.η Z ∘ g ∘ f ≈⟨ sym-assoc ○ ⟺ identityˡ ⟩ C.id ∘ (η.η Z ∘ g) ∘ f ≈˘⟨ pull-first M.identityˡ ⟩ μ.η Z ∘ (F₁ (η.η Z) ∘ η.η Z ∘ g) ∘ f ≈⟨ refl⟩∘⟨ pushʳ (η.commute g) ⟩∘⟨refl ⟩ μ.η Z ∘ ((F₁ (η.η Z) ∘ F₁ g) ∘ η.η Y) ∘ f ≈˘⟨ center (∘-resp-≈ˡ homomorphism) ⟩ (μ.η Z ∘ F₁ (η.η Z ∘ g)) ∘ η.η Y ∘ f ∎ ; F-resp-≈ = ∘-resp-≈ʳ } FF≃F : Forgetful ∘F Free ≃ M.F FF≃F = record { F⇒G = ntHelper record { η = λ X → F₁ C.id ; commute = λ {X Y} f → begin F₁ C.id ∘ μ.η Y ∘ F₁ (η.η Y ∘ f) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ homomorphism ⟩ F₁ C.id ∘ μ.η Y ∘ F₁ (η.η Y) ∘ F₁ f ≈⟨ refl⟩∘⟨ cancelˡ M.identityˡ ⟩ F₁ C.id ∘ F₁ f ≈⟨ [ M.F ]-resp-square id-comm-sym ⟩ F₁ f ∘ F₁ C.id ∎ } ; F⇐G = ntHelper record { η = λ X → F₁ C.id ; commute = λ {X Y} f → begin F₁ C.id ∘ F₁ f ≈⟨ [ M.F ]-resp-square id-comm-sym ⟩ F₁ f ∘ F₁ C.id ≈˘⟨ cancelˡ M.identityˡ ⟩∘⟨refl ⟩ (μ.η Y ∘ F₁ (η.η Y) ∘ F₁ f) ∘ F₁ C.id ≈˘⟨ ∘-resp-≈ʳ homomorphism ⟩∘⟨refl ⟩ (μ.η Y ∘ F₁ (η.η Y ∘ f)) ∘ F₁ C.id ∎ } ; iso = λ X → record { isoˡ = elimˡ identity ○ identity ; isoʳ = elimˡ identity ○ identity } } Free⊣Forgetful : Free ⊣ Forgetful Free⊣Forgetful = record { unit = ntHelper record { η = η.η ; commute = λ {X Y} f → begin η.η Y ∘ f ≈⟨ η.commute f ⟩ F₁ f ∘ η.η X ≈˘⟨ cancelˡ M.identityˡ ⟩∘⟨refl ⟩ (μ.η Y ∘ F₁ (η.η Y) ∘ F₁ f) ∘ η.η X ≈˘⟨ ∘-resp-≈ʳ homomorphism ⟩∘⟨refl ⟩ (μ.η Y ∘ F₁ (η.η Y ∘ f)) ∘ η.η X ∎ } ; counit = ntHelper record { η = λ X → F₁ C.id ; commute = λ {X Y} f → begin (μ.η Y ∘ F₁ (F₁ C.id)) ∘ η.η (F₀ Y) ∘ μ.η Y ∘ F₁ f ≈⟨ elimʳ (F-resp-≈ identity ○ identity) ⟩∘⟨refl ⟩ μ.η Y ∘ η.η (F₀ Y) ∘ μ.η Y ∘ F₁ f ≈⟨ cancelˡ M.identityʳ ⟩ μ.η Y ∘ F₁ f ≈⟨ introʳ identity ⟩ (μ.η Y ∘ F₁ f) ∘ F₁ C.id ∎ } ; zig = λ {A} → begin (μ.η A ∘ F₁ (F₁ C.id)) ∘ η.η (F₀ A) ∘ η.η A ≈⟨ elimʳ (F-resp-≈ identity ○ identity) ⟩∘⟨refl ⟩ μ.η A ∘ η.η (F₀ A) ∘ η.η A ≈⟨ cancelˡ M.identityʳ ⟩ η.η A ∎ ; zag = λ {B} → begin (μ.η B ∘ F₁ (F₁ C.id)) ∘ η.η (F₀ B) ≈⟨ elimʳ (F-resp-≈ identity ○ identity) ⟩∘⟨refl ⟩ μ.η B ∘ η.η (F₀ B) ≈⟨ M.identityʳ ⟩ C.id ∎ } module KleisliExtension where κ : {A B : Obj} → (f : A ⇒ F₀ B) → F₀ A ⇒ F₀ B κ {_} {B} f = μ.η B ∘ F₁ f f-iso⇒Klf-iso : ∀ {A B : Obj} → (f : A ⇒ F₀ B) → (g : B ⇒ F₀ A) → Iso (Kleisli M) g f → Iso C (κ f) (κ g) f-iso⇒Klf-iso {A} {B} f g (record { isoˡ = isoˡ ; isoʳ = isoʳ }) = record { isoˡ = begin (μ.η A ∘ F₁ g) ∘ μ.η B ∘ F₁ f ≈⟨ center (sym (μ.commute g)) ⟩ μ.η A ∘ (μ.η (F₀ A) ∘ F₁ (F₁ g)) ∘ F₁ f ≈⟨ assoc²δγ ○ pushˡ M.sym-assoc ⟩ μ.η A ∘ F₁ (μ.η A) ∘ F₁ (F₁ g) ∘ F₁ f ≈⟨ refl⟩∘⟨ sym trihom ⟩ μ.η A ∘ F₁ (μ.η A ∘ F₁ g ∘ f) ≈⟨ refl⟩∘⟨ F-resp-≈ sym-assoc ⟩ μ.η A ∘ F₁ ((μ.η A ∘ F₁ g) ∘ f) ≈⟨ refl⟩∘⟨ F-resp-≈ isoʳ ○ M.identityˡ ⟩ C.id ∎ ; isoʳ = begin (μ.η B ∘ F₁ f) ∘ μ.η A ∘ F₁ g ≈⟨ center (sym (μ.commute f)) ⟩ μ.η B ∘ (μ.η (F₀ B) ∘ F₁ (F₁ f)) ∘ F₁ g ≈⟨ assoc²δγ ○ pushˡ M.sym-assoc ⟩ μ.η B ∘ F₁ (μ.η B) ∘ F₁ (F₁ f) ∘ F₁ g ≈⟨ refl⟩∘⟨ sym trihom ⟩ μ.η B ∘ F₁ (μ.η B ∘ F₁ f ∘ g) ≈⟨ refl⟩∘⟨ F-resp-≈ sym-assoc ⟩ μ.η B ∘ F₁ ((μ.η B ∘ F₁ f) ∘ g) ≈⟨ refl⟩∘⟨ F-resp-≈ isoˡ ○ M.identityˡ ⟩ C.id ∎ } where trihom : {X Y Z W : Obj} {f : X ⇒ Y} {g : Y ⇒ Z} {h : Z ⇒ W} → F₁ (h ∘ g ∘ f) ≈ F₁ h ∘ F₁ g ∘ F₁ f trihom {X} {Y} {Z} {W} {f} {g} {h} = begin F₁ (h ∘ g ∘ f) ≈⟨ homomorphism ⟩ F₁ h ∘ F₁ (g ∘ f) ≈⟨ refl⟩∘⟨ homomorphism ⟩ F₁ h ∘ F₁ g ∘ F₁ f ∎ Klf-iso⇒f-iso : ∀ {A B : Obj} → (f : A ⇒ F₀ B) → (g : B ⇒ F₀ A) → Iso C (κ f) (κ g) → Iso (Kleisli M) g f Klf-iso⇒f-iso {A} {B} f g record { isoˡ = isoˡ ; isoʳ = isoʳ } = record { isoˡ = begin (μ.η B ∘ F₁ f) ∘ g ≈⟨ introʳ M.identityʳ ⟩∘⟨refl ⟩ ((μ.η B ∘ F₁ f) ∘ (μ.η A ∘ η.η (F₀ A))) ∘ g ≈⟨ assoc ⟩∘⟨refl ○ assoc ○ refl⟩∘⟨ assoc ○ refl⟩∘⟨ refl⟩∘⟨ assoc ⟩ μ.η B ∘ F₁ f ∘ (μ.η A) ∘ (η.η (F₀ A) ∘ g) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ refl⟩∘⟨ η.commute g ⟩ μ.η B ∘ F₁ f ∘ μ.η A ∘ (F₁ g ∘ η.η B) ≈˘⟨ assoc ⟩∘⟨refl ○ assoc ○ refl⟩∘⟨ assoc ○ refl⟩∘⟨ refl⟩∘⟨ assoc ⟩ ((μ.η B ∘ F₁ f) ∘ μ.η A ∘ F₁ g) ∘ η.η B ≈⟨ elimˡ isoʳ ⟩ η.η B ∎ ; isoʳ = begin (μ.η A ∘ F₁ g) ∘ f ≈⟨ introʳ M.identityʳ ⟩∘⟨refl ⟩ ((μ.η A ∘ F₁ g) ∘ (μ.η B ∘ η.η (F₀ B))) ∘ f ≈⟨ assoc ⟩∘⟨refl ○ assoc ○ refl⟩∘⟨ assoc ○ refl⟩∘⟨ refl⟩∘⟨ assoc ⟩ μ.η A ∘ F₁ g ∘ (μ.η B) ∘ (η.η (F₀ B) ∘ f) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ refl⟩∘⟨ η.commute f ⟩ μ.η A ∘ F₁ g ∘ μ.η B ∘ (F₁ f ∘ η.η A) ≈˘⟨ assoc ⟩∘⟨refl ○ assoc ○ refl⟩∘⟨ assoc ○ refl⟩∘⟨ refl⟩∘⟨ assoc ⟩ ((μ.η A ∘ F₁ g) ∘ μ.η B ∘ F₁ f) ∘ η.η A ≈⟨ elimˡ isoˡ ⟩ η.η A ∎ } kl-ext-compat : ∀ {A B X : Obj} → (f : A ⇒ F₀ B) → (g : B ⇒ F₀ X) → κ ((κ g) ∘ f) ≈ κ g ∘ κ f kl-ext-compat {A} {B} {X} f g = begin μ.η X ∘ F₁ ((μ.η X ∘ F₁ g) ∘ f) ≈⟨ refl⟩∘⟨ F-resp-≈ assoc ○ refl⟩∘⟨ trihom ⟩ μ.η X ∘ (F₁ (μ.η X) ∘ F₁ (F₁ g) ∘ F₁ f) ≈⟨ sym-assoc ⟩ (μ.η X ∘ F₁ (μ.η X)) ∘ F₁ (F₁ g) ∘ F₁ f ≈⟨ M.assoc ⟩∘⟨refl ⟩ (μ.η X ∘ μ.η (F₀ X)) ∘ F₁ (F₁ g) ∘ F₁ f ≈⟨ center (μ.commute g) ⟩ μ.η X ∘ (F₁ g ∘ μ.η B) ∘ F₁ f ≈⟨ sym-assoc ○ (sym-assoc ⟩∘⟨refl) ○ assoc ⟩ (μ.η X ∘ F₁ g) ∘ μ.η B ∘ F₁ f ∎ where trihom : {X Y Z W : Obj} {f : X ⇒ Y} {g : Y ⇒ Z} {h : Z ⇒ W} → F₁ (h ∘ g ∘ f) ≈ F₁ h ∘ F₁ g ∘ F₁ f trihom {X} {Y} {Z} {W} {f} {g} {h} = begin F₁ (h ∘ g ∘ f) ≈⟨ homomorphism ⟩ F₁ h ∘ F₁ (g ∘ f) ≈⟨ refl⟩∘⟨ homomorphism ⟩ F₁ h ∘ F₁ g ∘ F₁ f ∎