module Cat.Functor.Adjoint.Cofree
  {o  o' ℓ'} {C : Precategory o } {D : Precategory o' ℓ'} where

Cofree objects🔗

Cofree objects are formally dual to free objects, as opposed to coffee objects.

  record Cofree-object (X : D.Ob) : Type (adj-level C D) where
    field
      {cofree} : C.Ob
      counit   : D.Hom (F₀ cofree) X

      unfold    :  {Y} (f : D.Hom (F₀ Y) X)  C.Hom Y cofree
      commute :  {Y} {f : D.Hom (F₀ Y) X}  counit D.∘ F₁ (unfold f)  f
      unique
        :  {Y} {f : D.Hom (F₀ Y) X} (g : C.Hom Y cofree)
         counit D.∘ F₁ g  f
         g  unfold f
  co-free→cofree :  {X}  Free-object F.op X  Cofree-object F X
  co-free→cofree free = record
    { Free-object free renaming (free to cofree; fold to unfold; unit to counit) }

  cofree→co-free :  {X}  Cofree-object F X  Free-object F.op X
  cofree→co-free cofree = record
    { Cofree-object cofree renaming
      (cofree to free; unfold to fold; counit to unit) }

  right-adjoint→cofree-objects : {U : Functor D C}  F  U   X  Cofree-object F X
  right-adjoint→cofree-objects F⊣U =
    co-free→cofree  left-adjoint→free-objects (opposite-adjunction F⊣U)

  cofree-objects→right-adjoint
    : (∀ X  Cofree-object F X)  (Σ[ U  Functor D C ] F  U)
  cofree-objects→right-adjoint cofree-objs = _ , adjoint-natural-isol ni adj where
    ni : unopF F.op ≅ⁿ F
    ni = trivial-isoⁿ!

    adj : unopF F.op  _
    adj = unop-adjunction (free-objects≃left-adjoint .fst (cofree→co-free  cofree-objs) .snd)