module Cat.Diagram.Comonad.Writer whereWriter (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 () publicTo 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 .Ξ΄-unitl = uniqueβ
    (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β cancelr Οβββ¨β©)
    (idr _) (idr _)
  Writer-comonad .Ξ΄-unitr = Οβββ¨β©
  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 β) (cartesian : Cartesian-category C) (A : β C β) where
  open Cartesian-category cartesianThe 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 cartesian) A β Monad-on (Writer C A (products 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! products
    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! products β lemma) (products! products) (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! products β lemma) (products! products) (idr Οβ) (idr Οβ)
    mk .ΞΌ-assoc {x} =
      let
        lemma =
          Οβ β β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β β¨ Οβ , β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β© β Οβ β©
            β‘Λβ¨ products! products β©
          m.ΞΌ β β¨ id β Οβ , m.ΞΌ β Οβ β© β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β©
            β‘β¨ extendl m.ΞΌ-assoc β©
          m.ΞΌ β (β¨ m.ΞΌ β Οβ , id β Οβ β© β β¨ β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β©) β β¨ Οβ , β¨ Οβ , Οβ β Οβ β© β Οβ β©
            β‘β¨ products! products β©
          m.ΞΌ β β¨ m.ΞΌ β β¨ Οβ , Οβ β Οβ β© , Οβ β Οβ β Οβ β©
            β
      in β¨β©-uniqueβ lemma (products! products)
        (pulll Οβββ¨β© β pullr (β¨β©-unique (pulll Οβββ¨β© β Οβββ¨β©) (pulll Οβββ¨β© β pullr Οβββ¨β©)))
        (pulll Οβββ¨β© β pullr Οβββ¨β©)