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.
Writer : 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 Οβββ¨β©))
Since weβve already decided that the comonad structure is built on dropping and duplicating, our structure maps are essentially forced on us:
Writer-comonad : Comonad-on Writer Writer-comonad .counit .Ξ· x = Οβ Writer-comonad .comult .Ξ· x = β¨ Οβ , id β©
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.
Writer-comonad .counit .is-natural x y f = Οβββ¨β© Writer-comonad .comult .is-natural x y f = uniqueβ (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β idl _) (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β cancelr Οβββ¨β©) Writer-comonad .Ξ΄-idl = uniqueβ (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β cancelr Οβββ¨β©) (idr _) (idr _) Writer-comonad .Ξ΄-idr = Οβββ¨β© Writer-comonad .Ξ΄-assoc = β¨β©β _ β apβ β¨_,_β© refl (pullr Οβββ¨β© β id-comm) β sym (β¨β©β _)
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)) monoidβwriter-monad monoid = mk where module m = Monoid-on monoid mk : Monad-on _ mk .unit .Ξ· x = β¨ m.Ξ· β ! , id β© mk .mult .Ξ· x = β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β©
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.
mk .unit .is-natural x y f = β¨β©-uniqueβ (pulll Οβββ¨β©) (pulll Οβββ¨β© β idl f) (pulll Οβββ¨β© β Οβββ¨β© β sym (pullr (sym (!-unique _)))) (pulll Οβββ¨β© β pullr Οβββ¨β© β idr f) mk .mult .is-natural x y f = products! prods mk .ΞΌ-unitr = let lemma = m.ΞΌ β β¨ Οβ , m.Ξ· β ! β Οβ β© β‘Λβ¨ apβ _β_ refl (β¨β©-unique (pulll Οβββ¨β© β pullr Οβββ¨β© β idl Οβ) (pulll Οβββ¨β© β pullr Οβββ¨β© β apβ _β_ refl (!-unique _))) β©β‘Λ m.ΞΌ β β¨ id β Οβ , m.Ξ· β Οβ β© β β¨ Οβ , ! β© β‘β¨ pulll m.ΞΌ-unitr β©β‘ Οβ β β¨ Οβ , ! β© β‘β¨ Οβββ¨β© β©β‘ Οβ β in β¨β©-uniqueβ (products! prods β lemma) (products! prods) (idr Οβ) (idr Οβ) mk .ΞΌ-unitl = let lemma = m.ΞΌ β β¨ m.Ξ· β ! , Οβ β© β‘Λβ¨ apβ _β_ refl (β¨β©-unique (pulll Οβββ¨β© β pullr Οβββ¨β©) (pulll Οβββ¨β© β pullr Οβββ¨β© β idl Οβ)) β©β‘Λ m.ΞΌ β β¨ m.Ξ· β Οβ , id β Οβ β© β β¨ ! , Οβ β© β‘β¨ pulll m.ΞΌ-unitl β©β‘ Οβ β β¨ ! , Οβ β© β‘β¨ Οβββ¨β© β©β‘ Οβ β in β¨β©-uniqueβ (products! prods β lemma) (products! prods) (idr Οβ) (idr Οβ) mk .ΞΌ-assoc {x} = let lemma = Οβ β β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β β¨ Οβ , β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β Οβ β© β‘Λβ¨ products! prods β©β‘Λ m.ΞΌ β β¨ id β Οβ , m.ΞΌ β Οβ β© β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β© β‘β¨ extendl m.ΞΌ-assoc β©β‘ m.ΞΌ β (β¨ m.ΞΌ β Οβ , id β Οβ β© β β¨ β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β©) β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β© β‘β¨ products! prods β©β‘ m.ΞΌ β β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β Οβ β© β in β¨β©-uniqueβ lemma (products! prods) (pulll Οβββ¨β© β pullr (β¨β©-unique (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β pullr Οβββ¨β©))) (pulll Οβββ¨β© β pullr Οβββ¨β©)