module Cat.Diagram.Comonad.Writer where
Writer (co)monadsπ
If is an object in a Cartesian monoidal category then the functor βproduct with β functor, can naturally be equipped with the structure of a comonad. This structure embodies a particular view of as a resource, which in particular can be freely dropped and duplicated. Dropping is necessary to form the counit map and duplicating becomes the comultiplication
module _ {o β} (C : Precategory o β) (A : β C β) (prod : β B β Product C A B) where
open Cat C
private module _ {B} where open Product (prod B) using (β¨_,_β© ; Οβ ; Οβ ; Οβββ¨β© ; Οβββ¨β© ; β¨β©β ; unique ; uniqueβ) public
private module _ B where open Product (prod B) renaming (apex to AΓ) using () public
To functional programmers, the functor
is of particular importance when
is equipped with a monoid structure, in which case we can make
into a monad: the Writer
monad with values in
We will keep with this name even in the comonadic setting.
: Functor C C
Writer .Fβ = AΓ
Writer .Fβ f = β¨ Οβ , f β Οβ β©
Writer .F-id = sym (unique (idr _) id-comm)
Writer .F-β f g = sym (unique (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β extendr Οβββ¨β©)) Writer
Since weβve already decided that the comonad structure is built on dropping and duplicating, our structure maps are essentially forced on us:
: Comonad-on Writer
Writer-comonad .counit .Ξ· x = Οβ
Writer-comonad .comult .Ξ· x = β¨ Οβ , id β© Writer-comonad
The proof that these maps equip
with a comonad structure are routine reasoning about products, and so we
will leave them in this <details>
block for the curious reader.
.counit .is-natural x y f = Οβββ¨β©
Writer-comonad .comult .is-natural x y f = uniqueβ
Writer-comonad (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β idl _)
(pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β cancelr Οβββ¨β©)
.Ξ΄-idl = uniqueβ
Writer-comonad (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β cancelr Οβββ¨β©)
(idr _) (idr _)
.Ξ΄-idr = Οβββ¨β©
Writer-comonad .Ξ΄-assoc = β¨β©β _ β apβ β¨_,_β© refl (pullr Οβββ¨β© β id-comm) β sym (β¨β©β _) Writer-comonad
Writer monadsπ
We will now prove that the construction of Writer
as a monad, familiar from
functional programming, works in the generality of letting
be an arbitrary Cartesian monoidal category, and with
equipped with an arbitrary monoid structure.
module _ {o β} (C : Precategory o β) (prods : β A B β Product C A B) (term : Terminal C) (A : β C β) where
open Binary-products C prods
open Terminal term
open Cat C
The key take-away is that the usual definition works: at the level of generalised elements, the unit of the monad maps to where is the unit of the monoid; similarly, the multiplication sends to where we write the monoidβs multiplication by juxtaposition.
monoidβwriter-monad: Monoid-on (Cartesian-monoidal prods term) A β Monad-on (Writer C A (prods A))
= mk where
monoidβwriter-monad monoid module m = Monoid-on monoid
: Monad-on _
mk .unit .Ξ· x = β¨ m.Ξ· β ! , id β©
mk .mult .Ξ· x = β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© mk
Above, we have written these structure maps in point-free style. The proof strategy for showing that these obey the monad laws is noting that this can be shown componentwise. On the β componentβ of the pair, we have a monoid law; and the right component is preserved. Implementing this is, again, mostly an exercise in dealing with products.
.unit .is-natural x y f = β¨β©-uniqueβ (pulll Οβββ¨β©) (pulll Οβββ¨β© β idl f)
mk (pulll Οβββ¨β© β Οβββ¨β© β sym (pullr (sym (!-unique _))))
(pulll Οβββ¨β© β pullr Οβββ¨β© β idr f)
.mult .is-natural x y f = products! prods
mk .ΞΌ-unitr =
mk let
=
lemma .ΞΌ β β¨ Οβ , m.Ξ· β ! β Οβ β© β‘Λβ¨ apβ _β_ refl (β¨β©-unique (pulll Οβββ¨β© β pullr Οβββ¨β© β idl Οβ) (pulll Οβββ¨β© β pullr Οβββ¨β© β apβ _β_ refl (!-unique _))) β©
m.ΞΌ β β¨ id β Οβ , m.Ξ· β Οβ β© β β¨ Οβ , ! β© β‘β¨ pulll m.ΞΌ-unitr β©
m
Οβ β β¨ Οβ , ! β© β‘β¨ Οβββ¨β© β©
Οβ βin β¨β©-uniqueβ (products! prods β lemma) (products! prods) (idr Οβ) (idr Οβ)
.ΞΌ-unitl =
mk let
=
lemma .ΞΌ β β¨ m.Ξ· β ! , Οβ β© β‘Λβ¨ apβ _β_ refl (β¨β©-unique (pulll Οβββ¨β© β pullr Οβββ¨β©) (pulll Οβββ¨β© β pullr Οβββ¨β© β idl Οβ)) β©
m.ΞΌ β β¨ m.Ξ· β Οβ , id β Οβ β© β β¨ ! , Οβ β© β‘β¨ pulll m.ΞΌ-unitl β©
m
Οβ β β¨ ! , Οβ β© β‘β¨ Οβββ¨β© β©
Οβ βin β¨β©-uniqueβ (products! prods β lemma) (products! prods) (idr Οβ) (idr Οβ)
.ΞΌ-assoc {x} =
mk let
=
lemma .ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β β¨ Οβ , β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β Οβ β©
Οβ β β¨ m
β‘Λβ¨ products! prods β©.ΞΌ β β¨ id β Οβ , m.ΞΌ β Οβ β© β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β©
m.ΞΌ-assoc β©
β‘β¨ extendl m.ΞΌ β (β¨ m.ΞΌ β Οβ , id β Οβ β© β β¨ β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β©) β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β©
m
β‘β¨ products! prods β©.ΞΌ β β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β Οβ β©
m
βin β¨β©-uniqueβ lemma (products! prods)
(pulll Οβββ¨β© β pullr (β¨β©-unique (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β pullr Οβββ¨β©)))
(pulll Οβββ¨β© β pullr Οβββ¨β©)