2018-02-24 14:13:25 +00:00
|
|
|
|
{-# OPTIONS --cubical --allow-unsolved-metas #-}
|
2018-02-23 16:33:09 +00:00
|
|
|
|
module Cat.Category.Monad where
|
|
|
|
|
|
2018-02-24 11:52:16 +00:00
|
|
|
|
open import Agda.Primitive
|
|
|
|
|
|
|
|
|
|
open import Data.Product
|
|
|
|
|
|
2018-02-23 16:33:09 +00:00
|
|
|
|
open import Cubical
|
|
|
|
|
|
|
|
|
|
open import Cat.Category
|
2018-02-24 11:52:16 +00:00
|
|
|
|
open import Cat.Category.Functor as F
|
|
|
|
|
open import Cat.Category.NaturalTransformation
|
2018-02-23 16:33:09 +00:00
|
|
|
|
open import Cat.Categories.Fun
|
2018-02-24 11:52:16 +00:00
|
|
|
|
|
2018-02-24 14:13:25 +00:00
|
|
|
|
-- "A monad in the monoidal form" [voe]
|
2018-02-24 11:52:16 +00:00
|
|
|
|
module Monoidal {ℓa ℓb : Level} (ℂ : Category ℓa ℓb) where
|
|
|
|
|
private
|
|
|
|
|
ℓ = ℓa ⊔ ℓb
|
|
|
|
|
|
|
|
|
|
open Category ℂ hiding (IsAssociative)
|
|
|
|
|
open NaturalTransformation ℂ ℂ
|
|
|
|
|
record RawMonad : Set ℓ where
|
|
|
|
|
field
|
2018-02-24 19:37:21 +00:00
|
|
|
|
-- R ~ m
|
2018-02-24 11:52:16 +00:00
|
|
|
|
R : Functor ℂ ℂ
|
2018-02-24 19:37:21 +00:00
|
|
|
|
-- η ~ pure
|
2018-02-24 11:52:16 +00:00
|
|
|
|
ηNat : NaturalTransformation F.identity R
|
2018-02-24 19:37:21 +00:00
|
|
|
|
-- μ ~ join
|
2018-02-24 11:52:16 +00:00
|
|
|
|
μNat : NaturalTransformation F[ R ∘ R ] R
|
|
|
|
|
|
2018-02-24 14:13:25 +00:00
|
|
|
|
η : Transformation F.identity R
|
|
|
|
|
η = proj₁ ηNat
|
|
|
|
|
μ : Transformation F[ R ∘ R ] R
|
|
|
|
|
μ = proj₁ μNat
|
2018-02-24 13:00:52 +00:00
|
|
|
|
|
2018-02-24 11:52:16 +00:00
|
|
|
|
private
|
2018-02-24 13:00:52 +00:00
|
|
|
|
module R = Functor R
|
|
|
|
|
module RR = Functor F[ R ∘ R ]
|
2018-02-24 11:52:16 +00:00
|
|
|
|
module _ {X : Object} where
|
|
|
|
|
IsAssociative' : Set _
|
2018-02-24 18:07:58 +00:00
|
|
|
|
IsAssociative' = μ X ∘ R.func→ (μ X) ≡ μ X ∘ μ (R.func* X)
|
2018-02-24 11:52:16 +00:00
|
|
|
|
IsInverse' : Set _
|
|
|
|
|
IsInverse'
|
2018-02-24 18:07:58 +00:00
|
|
|
|
= μ X ∘ η (R.func* X) ≡ 𝟙
|
|
|
|
|
× μ X ∘ R.func→ (η X) ≡ 𝟙
|
2018-02-24 11:52:16 +00:00
|
|
|
|
|
|
|
|
|
-- We don't want the objects to be indexes of the type, but rather just
|
|
|
|
|
-- universally quantify over *all* objects of the category.
|
|
|
|
|
IsAssociative = {X : Object} → IsAssociative' {X}
|
|
|
|
|
IsInverse = {X : Object} → IsInverse' {X}
|
|
|
|
|
|
|
|
|
|
record IsMonad (raw : RawMonad) : Set ℓ where
|
|
|
|
|
open RawMonad raw public
|
|
|
|
|
field
|
|
|
|
|
isAssociative : IsAssociative
|
|
|
|
|
isInverse : IsInverse
|
2018-02-24 13:00:52 +00:00
|
|
|
|
|
2018-02-24 13:01:57 +00:00
|
|
|
|
record Monad : Set ℓ where
|
|
|
|
|
field
|
|
|
|
|
raw : RawMonad
|
|
|
|
|
isMonad : IsMonad raw
|
|
|
|
|
open IsMonad isMonad public
|
2018-02-24 19:37:21 +00:00
|
|
|
|
module R = Functor R
|
|
|
|
|
module RR = Functor F[ R ∘ R ]
|
|
|
|
|
module _ {X Y Z : _} {g : ℂ [ Y , R.func* Z ]} {f : ℂ [ X , R.func* Y ]} where
|
|
|
|
|
lem : μ Z ∘ R.func→ g ∘ (μ Y ∘ R.func→ f) ≡ μ Z ∘ R.func→ (μ Z ∘ R.func→ g ∘ f)
|
|
|
|
|
lem = begin
|
|
|
|
|
μ Z ∘ R.func→ g ∘ (μ Y ∘ R.func→ f) ≡⟨ {!!} ⟩
|
|
|
|
|
μ Z ∘ R.func→ (μ Z ∘ R.func→ g ∘ f) ∎
|
|
|
|
|
where
|
|
|
|
|
open Category ℂ using () renaming (isAssociative to c-assoc)
|
|
|
|
|
μN : Natural F[ R ∘ R ] R μ
|
|
|
|
|
-- μN : (f : ℂ [ Y , R.func* Z ]) → μ (R.func* Z) ∘ RR.func→ f ≡ R.func→ f ∘ μ Y
|
|
|
|
|
μN = proj₂ μNat
|
|
|
|
|
μg : μ (R.func* Z) ∘ RR.func→ g ≡ R.func→ g ∘ μ Y
|
|
|
|
|
μg = μN g
|
|
|
|
|
μf : μ (R.func* Y) ∘ RR.func→ f ≡ R.func→ f ∘ μ X
|
|
|
|
|
μf = μN f
|
|
|
|
|
ηN : Natural F.identity R η
|
|
|
|
|
ηN = proj₂ ηNat
|
|
|
|
|
ηg : η (R.func* Z) ∘ g ≡ R.func→ g ∘ η Y
|
|
|
|
|
ηg = ηN g
|
|
|
|
|
-- Alternate route:
|
|
|
|
|
res = begin
|
|
|
|
|
μ Z ∘ R.func→ g ∘ (μ Y ∘ R.func→ f) ≡⟨ c-assoc ⟩
|
|
|
|
|
μ Z ∘ R.func→ g ∘ μ Y ∘ R.func→ f ≡⟨ {!!} ⟩
|
|
|
|
|
μ Z ∘ (R.func→ g ∘ μ Y) ∘ R.func→ f ≡⟨ {!!} ⟩
|
|
|
|
|
μ Z ∘ (μ (R.func* Z) ∘ RR.func→ g) ∘ R.func→ f ≡⟨ {!!} ⟩
|
|
|
|
|
μ Z ∘ R.func→ (μ Z ∘ R.func→ g ∘ f) ∎
|
2018-02-24 13:01:57 +00:00
|
|
|
|
|
2018-02-24 14:13:25 +00:00
|
|
|
|
-- "A monad in the Kleisli form" [voe]
|
2018-02-24 13:00:52 +00:00
|
|
|
|
module Kleisli {ℓa ℓb : Level} (ℂ : Category ℓa ℓb) where
|
|
|
|
|
private
|
|
|
|
|
ℓ = ℓa ⊔ ℓb
|
|
|
|
|
|
|
|
|
|
open Category ℂ hiding (IsIdentity)
|
|
|
|
|
record RawMonad : Set ℓ where
|
|
|
|
|
field
|
|
|
|
|
RR : Object → Object
|
2018-02-24 14:13:25 +00:00
|
|
|
|
-- Note name-change from [voe]
|
|
|
|
|
ζ : {X : Object} → ℂ [ X , RR X ]
|
2018-02-24 13:00:52 +00:00
|
|
|
|
rr : {X Y : Object} → ℂ [ X , RR Y ] → ℂ [ RR X , RR Y ]
|
2018-02-24 14:25:07 +00:00
|
|
|
|
-- Note the correspondance with Haskell:
|
|
|
|
|
--
|
|
|
|
|
-- RR ~ m
|
|
|
|
|
-- ζ ~ pure
|
|
|
|
|
-- rr ~ flip (>>=)
|
|
|
|
|
--
|
|
|
|
|
-- Where those things have these types:
|
|
|
|
|
--
|
|
|
|
|
-- m : 𝓤 → 𝓤
|
|
|
|
|
-- pure : x → m x
|
|
|
|
|
-- flip (>>=) :: (a → m b) → m a → m b
|
|
|
|
|
--
|
2018-02-24 18:08:20 +00:00
|
|
|
|
pure : {X : Object} → ℂ [ X , RR X ]
|
|
|
|
|
pure = ζ
|
|
|
|
|
-- Why is (>>=) not implementable?
|
|
|
|
|
--
|
|
|
|
|
-- (>>=) : m a -> (a -> m b) -> m b
|
|
|
|
|
-- (>=>) : (a -> m b) -> (b -> m c) -> a -> m c
|
|
|
|
|
_>=>_ : {A B C : Object} → ℂ [ A , RR B ] → ℂ [ B , RR C ] → ℂ [ A , RR C ]
|
2018-02-24 19:41:47 +00:00
|
|
|
|
f >=> g = rr g ∘ f
|
2018-02-24 18:08:20 +00:00
|
|
|
|
|
2018-02-24 19:37:21 +00:00
|
|
|
|
-- fmap id ≡ id
|
2018-02-24 13:00:52 +00:00
|
|
|
|
IsIdentity = {X : Object}
|
2018-02-24 14:13:25 +00:00
|
|
|
|
→ rr ζ ≡ 𝟙 {RR X}
|
2018-02-24 13:00:52 +00:00
|
|
|
|
IsNatural = {X Y : Object} (f : ℂ [ X , RR Y ])
|
2018-02-24 19:37:21 +00:00
|
|
|
|
→ rr f ∘ ζ ≡ f
|
2018-02-24 13:00:52 +00:00
|
|
|
|
IsDistributive = {X Y Z : Object} (g : ℂ [ Y , RR Z ]) (f : ℂ [ X , RR Y ])
|
2018-02-24 19:37:21 +00:00
|
|
|
|
→ rr g ∘ rr f ≡ rr (rr g ∘ f)
|
|
|
|
|
-- I assume `Fusion` is admissable - it certainly looks more like the
|
|
|
|
|
-- distributive law for monads I know from Haskell.
|
|
|
|
|
Fusion = {X Y Z : Object} (g : ℂ [ Y , Z ]) (f : ℂ [ X , Y ])
|
|
|
|
|
→ rr (ζ ∘ g ∘ f) ≡ rr (ζ ∘ g) ∘ rr (ζ ∘ f)
|
|
|
|
|
-- NatDist2Fus : IsNatural → IsDistributive → Fusion
|
|
|
|
|
-- NatDist2Fus isNatural isDistributive g f =
|
|
|
|
|
-- let
|
|
|
|
|
-- ζf = ζ ∘ f
|
|
|
|
|
-- ζg = ζ ∘ g
|
|
|
|
|
-- Nζf : rr (ζ ∘ f) ∘ ζ ≡ ζ ∘ f
|
|
|
|
|
-- Nζf = isNatural ζf
|
|
|
|
|
-- Nζg : rr (ζ ∘ g) ∘ ζ ≡ ζ ∘ g
|
|
|
|
|
-- Nζg = isNatural ζg
|
|
|
|
|
-- ζgf = ζ ∘ g ∘ f
|
|
|
|
|
-- Nζgf : rr (ζ ∘ g ∘ f) ∘ ζ ≡ ζ ∘ g ∘ f
|
|
|
|
|
-- Nζgf = isNatural ζgf
|
|
|
|
|
-- res : rr (ζ ∘ g ∘ f) ≡ rr (ζ ∘ g) ∘ rr (ζ ∘ f)
|
|
|
|
|
-- res = {!!}
|
|
|
|
|
-- in res
|
2018-02-24 13:00:52 +00:00
|
|
|
|
|
|
|
|
|
record IsMonad (raw : RawMonad) : Set ℓ where
|
|
|
|
|
open RawMonad raw public
|
|
|
|
|
field
|
|
|
|
|
isIdentity : IsIdentity
|
|
|
|
|
isNatural : IsNatural
|
|
|
|
|
isDistributive : IsDistributive
|
|
|
|
|
|
|
|
|
|
record Monad : Set ℓ where
|
|
|
|
|
field
|
|
|
|
|
raw : RawMonad
|
|
|
|
|
isMonad : IsMonad raw
|
|
|
|
|
open IsMonad isMonad public
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
|
|
|
|
-- Problem 2.3
|
|
|
|
|
module _ {ℓa ℓb : Level} {ℂ : Category ℓa ℓb} where
|
|
|
|
|
private
|
2018-02-24 18:07:58 +00:00
|
|
|
|
open Category ℂ using (Object ; Arrow ; 𝟙 ; _∘_)
|
2018-02-24 14:13:25 +00:00
|
|
|
|
open Functor using (func* ; func→)
|
|
|
|
|
module M = Monoidal ℂ
|
|
|
|
|
module K = Kleisli ℂ
|
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
-- Note similarity with locally defined things in Kleisly.RawMonad!!
|
2018-02-24 14:13:25 +00:00
|
|
|
|
module _ (m : M.RawMonad) where
|
|
|
|
|
private
|
|
|
|
|
open M.RawMonad m
|
|
|
|
|
module Kraw = K.RawMonad
|
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
RR : Object → Object
|
|
|
|
|
RR = func* R
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
ζ : {X : Object} → ℂ [ X , RR X ]
|
|
|
|
|
ζ {X} = η X
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
rr : {X Y : Object} → ℂ [ X , RR Y ] → ℂ [ RR X , RR Y ]
|
2018-02-24 19:41:47 +00:00
|
|
|
|
rr {X} {Y} f = μ Y ∘ func→ R f
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
|
|
|
|
forthRaw : K.RawMonad
|
|
|
|
|
Kraw.RR forthRaw = RR
|
|
|
|
|
Kraw.ζ forthRaw = ζ
|
|
|
|
|
Kraw.rr forthRaw = rr
|
|
|
|
|
|
|
|
|
|
module _ {raw : M.RawMonad} (m : M.IsMonad raw) where
|
|
|
|
|
open M.IsMonad m
|
2018-02-24 18:07:58 +00:00
|
|
|
|
open K.RawMonad (forthRaw raw)
|
2018-02-24 14:13:25 +00:00
|
|
|
|
module Kis = K.IsMonad
|
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
isIdentity : IsIdentity
|
|
|
|
|
isIdentity {X} = begin
|
|
|
|
|
rr ζ ≡⟨⟩
|
|
|
|
|
rr (η X) ≡⟨⟩
|
2018-02-24 19:41:47 +00:00
|
|
|
|
μ X ∘ func→ R (η X) ≡⟨ proj₂ isInverse ⟩
|
2018-02-24 18:07:58 +00:00
|
|
|
|
𝟙 ∎
|
|
|
|
|
|
|
|
|
|
module R = Functor R
|
|
|
|
|
isNatural : IsNatural
|
|
|
|
|
isNatural {X} {Y} f = begin
|
|
|
|
|
rr f ∘ ζ ≡⟨⟩
|
|
|
|
|
rr f ∘ η X ≡⟨⟩
|
|
|
|
|
μ Y ∘ R.func→ f ∘ η X ≡⟨ sym ℂ.isAssociative ⟩
|
|
|
|
|
μ Y ∘ (R.func→ f ∘ η X) ≡⟨ cong (λ φ → μ Y ∘ φ) (sym (ηN f)) ⟩
|
|
|
|
|
μ Y ∘ (η (R.func* Y) ∘ f) ≡⟨ ℂ.isAssociative ⟩
|
|
|
|
|
μ Y ∘ η (R.func* Y) ∘ f ≡⟨ cong (λ φ → φ ∘ f) (proj₁ isInverse) ⟩
|
|
|
|
|
𝟙 ∘ f ≡⟨ proj₂ ℂ.isIdentity ⟩
|
|
|
|
|
f ∎
|
|
|
|
|
where
|
|
|
|
|
open NaturalTransformation
|
2018-02-24 19:37:21 +00:00
|
|
|
|
module ℂ = Category ℂ
|
2018-02-24 18:07:58 +00:00
|
|
|
|
ηN : Natural ℂ ℂ F.identity R η
|
|
|
|
|
ηN = proj₂ ηNat
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
isDistributive : IsDistributive
|
2018-02-24 19:37:21 +00:00
|
|
|
|
isDistributive {X} {Y} {Z} g f = begin
|
|
|
|
|
rr g ∘ rr f ≡⟨⟩
|
|
|
|
|
μ Z ∘ R.func→ g ∘ (μ Y ∘ R.func→ f) ≡⟨ {!!} ⟩
|
|
|
|
|
μ Z ∘ R.func→ (μ Z ∘ R.func→ g ∘ f) ≡⟨⟩
|
|
|
|
|
μ Z ∘ R.func→ (rr g ∘ f) ∎
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
|
|
|
|
forthIsMonad : K.IsMonad (forthRaw raw)
|
|
|
|
|
Kis.isIdentity forthIsMonad = isIdentity
|
|
|
|
|
Kis.isNatural forthIsMonad = isNatural
|
|
|
|
|
Kis.isDistributive forthIsMonad = isDistributive
|
|
|
|
|
|
|
|
|
|
forth : M.Monad → K.Monad
|
|
|
|
|
Kleisli.Monad.raw (forth m) = forthRaw (M.Monad.raw m)
|
|
|
|
|
Kleisli.Monad.isMonad (forth m) = forthIsMonad (M.Monad.isMonad m)
|
|
|
|
|
|
2018-02-24 18:07:58 +00:00
|
|
|
|
back : K.Monad → M.Monad
|
|
|
|
|
back = {!!}
|
|
|
|
|
|
|
|
|
|
fortheq : (m : K.Monad) → forth (back m) ≡ m
|
2018-02-24 19:37:21 +00:00
|
|
|
|
fortheq m = {!!}
|
2018-02-24 18:07:58 +00:00
|
|
|
|
|
|
|
|
|
backeq : (m : M.Monad) → back (forth m) ≡ m
|
|
|
|
|
backeq = {!!}
|
|
|
|
|
|
|
|
|
|
open import Cubical.GradLemma
|
2018-02-24 14:13:25 +00:00
|
|
|
|
eqv : isEquiv M.Monad K.Monad forth
|
2018-02-24 18:07:58 +00:00
|
|
|
|
eqv = gradLemma forth back fortheq backeq
|
2018-02-24 14:13:25 +00:00
|
|
|
|
|
|
|
|
|
Monoidal≃Kleisli : M.Monad ≃ K.Monad
|
|
|
|
|
Monoidal≃Kleisli = forth , eqv
|