cat/src/Cat/Category/Monad.agda

203 lines
6.1 KiB
Agda
Raw Normal View History

{-# OPTIONS --cubical --allow-unsolved-metas #-}
module Cat.Category.Monad where
open import Agda.Primitive
open import Data.Product
open import Cubical
open import Cat.Category
open import Cat.Category.Functor as F
open import Cat.Category.NaturalTransformation
open import Cat.Categories.Fun
-- "A monad in the monoidal form" [voe]
module Monoidal {a b : Level} ( : Category a b) where
private
= a b
open Category hiding (IsAssociative)
open NaturalTransformation
record RawMonad : Set where
field
R : Functor
-- pure
ηNat : NaturalTransformation F.identity R
-- (>=>)
μNat : NaturalTransformation F[ R R ] R
η : Transformation F.identity R
η = proj₁ ηNat
μ : Transformation F[ R R ] R
μ = proj₁ μNat
2018-02-24 13:00:52 +00:00
private
2018-02-24 13:00:52 +00:00
module R = Functor R
module RR = Functor F[ R R ]
module _ {X : Object} where
IsAssociative' : Set _
2018-02-24 18:07:58 +00:00
IsAssociative' = μ X R.func→ (μ X) μ X μ (R.func* X)
IsInverse' : Set _
IsInverse'
2018-02-24 18:07:58 +00:00
= μ X η (R.func* X) 𝟙
× μ X R.func→ (η X) 𝟙
-- 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
-- "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
-- 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
--
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 ]
f >=> g = [ rr g f ]
2018-02-24 13:00:52 +00:00
IsIdentity = {X : Object}
rr ζ 𝟙 {RR X}
2018-02-24 13:00:52 +00:00
IsNatural = {X Y : Object} (f : [ X , RR Y ])
( [ rr f ζ ]) f
2018-02-24 13:00:52 +00:00
IsDistributive = {X Y Z : Object} (g : [ Y , RR Z ]) (f : [ X , RR Y ])
[ rr g rr f ] rr ( [ rr g f ])
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
-- 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 ; 𝟙 ; _∘_)
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!!
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 18:07:58 +00:00
R→ : {A B : Object} [ A , B ] [ RR A , RR B ]
R→ = func→ R
2018-02-24 18:07:58 +00:00
ζ : {X : Object} [ X , RR X ]
ζ {X} = η X
2018-02-24 18:07:58 +00:00
rr : {X Y : Object} [ X , RR Y ] [ RR X , RR Y ]
rr {X} {Y} f = [ μ Y func→ R f ]
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)
module Kis = K.IsMonad
2018-02-24 18:07:58 +00:00
isIdentity : IsIdentity
isIdentity {X} = begin
rr ζ ≡⟨⟩
rr (η X) ≡⟨⟩
[ μ X func→ R (η X) ] ≡⟨ proj₂ isInverse
𝟙
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
module = Category
open NaturalTransformation
ηN : Natural F.identity R η
ηN = proj₂ ηNat
2018-02-24 18:07:58 +00:00
isDistributive : IsDistributive
isDistributive = {!!}
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
fortheq = {!!}
backeq : (m : M.Monad) back (forth m) m
backeq = {!!}
open import Cubical.GradLemma
eqv : isEquiv M.Monad K.Monad forth
2018-02-24 18:07:58 +00:00
eqv = gradLemma forth back fortheq backeq
Monoidal≃Kleisli : M.Monad K.Monad
Monoidal≃Kleisli = forth , eqv