cat/src/Cat/Category/Monad.agda

252 lines
8.5 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 ~ m
R : Functor
-- η ~ pure
ηNat : NaturalTransformation F.identity R
-- μ ~ join
μ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
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
-- "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 ]
2018-02-24 19:41:47 +00:00
f >=> g = rr g f
-- fmap id ≡ id
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)
-- 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
-- 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
ζ : {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 ]
2018-02-24 19:41:47 +00:00
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) ≡⟨⟩
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
module = Category
2018-02-24 18:07:58 +00:00
ηN : Natural F.identity R η
ηN = proj₂ ηNat
2018-02-24 18:07:58 +00:00
isDistributive : IsDistributive
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)
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 m = {!!}
2018-02-24 18:07:58 +00:00
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