module Cat.Functor.Profunctor.Representation where

Profunctor representations🔗

Every functor induces, by precomposition with hom functor, a profunctor Fixing a profunctor we refer to the type of functors equipped with a natural isomorphism as the type of representations of

induced-profunctor : Functor C D  Profunctor C D _
induced-profunctor {D = D} = precompose₂ (Hom[-,-] D) Id

Representation : (R : Profunctor C D _)  Type (rep-level R)
Representation {C = C} {D = D} R =
  Σ[ F  Functor C D ] (R ≅ⁿ induced-profunctor F)

Functor presentations🔗

The notion of profunctor representation can be used to explain the “type-theoretic” presentation of universal constructions, that is, its presentation in terms of formation rules, introduction and elimination rules, and beta/eta laws. In particular, thinking of universal constructions in terms of profunctor representations explains the common “formula” for deriving functoriality of universal constructions from the type-theoretic presentation.

record Right-presentation (R : Profunctor C D _) : Type (rep-level R) where

Fix a profunctor Here, we focus on right functor presentations, which are best suited for “limit-like” universal constructions. Let us think of as the theory we are interested in studying, and write for of as a category of formation data for and, fixing and of the set as classifying introduction data for in context

A right functor presentation relative to consists, firstly, of a formation rule F₀, which turns a formation datum into actual object Using type-theoretic notation, we can imagine that represents the premises of a generic formation rule Additionally, we require an introduction rule intro, assigning to each a morphism Using our type-theoretic analogy, the element collects the premises of a generic introduction rule The appearance of on the right of the turnstile gives right presentations their name.

Since is a limit-like universal construction, the type theory of imagines it as a record-like type. From this perspective, we can think of an element as containing the values for projections in context and of the map as the constructed record value.

  field
    F₀    :  C    D 
    intro :  {Γ y}   R · Γ · y   D.Hom Γ (F₀ y)

We incorporate the elimination rules for by requiring a generic introduction datum univ, which associates a to each By the analogy above, we think of as a set of projections applied to a generic element of

    univ :  {c}   R · F₀ c · c 

Presenting the elimination rules in terms of a generic introduction datum is slightly confusing from a type-theoretic perspective, where it is more familiar to say that a term can be eliminated to obtain The reason for using a generic element is that it buys us naturality, i.e. stability under substitution, automatically. This is because we define elimination in terms of substitution, which in this case is the functorial action

  elim :  {Γ x}  D.Hom Γ (F₀ x)   R · Γ · x 
  elim h = R.lmap h univ

With this in hand, stating the laws becomes easy: the computation rule, beta, says that eliminating from an introduction form recovers the introduction datum; the uniqueness rule, eta, says that if projecting from recovers some projections then

  field
    beta :  {Γ y} {h :  R · Γ · y }  elim (intro h)  h
    unique
      :  {Γ y} {a :  R · Γ · y } {h : D.Hom Γ (F₀ y)}
       elim h  a  intro a  h

A short calculation recovers naturality of intro from functoriality of and the two laws.

  abstract
    intro-∘
      :  {Γ Δ z} {f : D.Hom Δ Γ} (h :  R · Γ · z )
       intro (R.lmap f h)  intro h D.∘ f
    intro-∘ {f = f} h = unique $
      elim (intro h D.∘ f)        ≡⟨ R.◀.expand refl ·ₚ _ 
      R.lmap f  elim (intro h)  ≡⟨ ap! beta 
      R.lmap f h                  

An example🔗

To exemplify the notion of right functor presentation, we can turn to the notion of product. Fixing a category we can simply take to be the category of formation data for products, since the data needed is exactly a pair of objects of The notion of introduction data for products is captured in the definition of product-profunctor, below, which says precisely that we are considering records built from pairs of and

Note that this definition is independent of whether or not actually has all products. We can work hypothetically with the data required to form pairs even if there are no actual pairs in

  product-profunctor : Profunctor (D ×ᶜ D) D 
  product-profunctor = make-bifunctor mk where
    open Make-bifunctor

    mk : Make-bifunctor
    mk .F₀   Γ (A , B) = el! (D.Hom Γ A × D.Hom Γ B)
    mk .lmap f g = g .fst D.∘ f , g .snd D.∘ f
    mk .rmap f g = f .fst D.∘ g .fst , f .snd D.∘ g .snd

A right presentation relative to this profunctor gives exactly an assignment of products in the presented functor is, modulo currying, the product bifunctor on Showing this amounts to shuffling around some data:

  products→presentation
    : (∀ X Y  Product D X Y)  Right-presentation product-profunctor
  products→presentation prods = record where
    open Binary-products D prods

    F₀ (X , Y)    = X ⊗₀ Y
    intro (f , g) =  f , g 
    univ          = π₁ , π₂
    unique p      = ⟨⟩-unique (ap fst p) (ap snd p)
    beta          = π₁∘⟨⟩ ,ₚ π₂∘⟨⟩

  representation→products
    : Right-presentation product-profunctor   X Y  Product D X Y
  representation→products rep X Y = record where
    module rep = Right-presentation rep

    apex = rep.F₀ (X , Y)
    π₁   = rep.univ .fst
    π₂   = rep.univ .snd
    has-is-product = record where
      ⟨_,_⟩  f g = rep.intro (f , g)
      π₁∘⟨⟩      = ap fst rep.beta
      π₂∘⟨⟩      = ap snd rep.beta
      unique p q = rep.unique (p ,ₚ q)

Presented functors🔗

With a motivating example out of the way, we can turn to calculating the functor presented by a right functor presentation. The object mapping is given by the introduction rule; the functorial action is obtained by subjecting the universal introduction datum to a “substitution” in the category of formation data, and introducing a map from this. Functoriality follows from straightforward, though lengthy, computations.

  presentation→functor : Functor C D
  presentation→functor .F₀   = p.F₀
  presentation→functor .F₁ f = intro (R.rmap f univ)
  presentation→functor .F-id = unique $
    R.lmap D.id univ ≡⟨ R.◀.elim refl  ·ₚ _ 
    univ             ≡⟨ R.▶.intro refl ·ₚ _ 
    R.rmap C.id univ 
  presentation→functor .F-∘ f g = sym $
    intro (R.rmap f univ) D.∘ intro (R.rmap g univ)          ≡˘⟨ p.intro-∘ _ ≡˘
    intro (R.lmap (intro (R.rmap g univ)) (R.rmap f univ))   ≡⟨ ap intro (R.lrmap _ _ ·ₚ _) 
    intro (R.rmap f  R.lmap (intro (R.rmap g univ)) univ ) ≡⟨ ap! beta 
    intro (R.rmap f (R.rmap g univ))                         ≡⟨ ap intro (R.▶.collapse refl ·ₚ univ) 
    intro (R.rmap (f C.∘ g) univ)                            

We can then show that this is a representation of by showing that the isomorphism furnished by intro and elim is suitably natural; note that one direction of naturality is simply intro-∘, shown above.

  presentation→representation : Representation R
  presentation→representation .fst = presentation→functor
  presentation→representation .snd =
    let
      module S = Cat (Sets ℓ')

      im :  x y  R · x · y S.≅ Hom[-,-] D · x · p.F₀ y
      im x y = S.make-iso intro p.elim
        (ext λ h  p.unique refl)
        (ext λ h  beta)

      nat
        :  {x y z} {f : C.Hom x y} (h :  R · z · x )
         intro (R.rmap f univ) D.∘ intro h  intro (R.rmap f h)
      nat {f = f} h =
        intro (R.rmap f univ) D.∘ intro h          ≡˘⟨ intro-∘ _ ≡˘
        intro  R.lmap (intro h) (R.rmap f univ)  ≡⟨ ap! (R.lrmap _ _ ·ₚ _) 
        intro (R.rmap f  R.lmap (intro h) univ ) ≡⟨ ap! beta 
        intro (R.rmap f h)                         
    in biiso→isoⁿ im  f  sym (ext p.intro-∘))  f  ext nat)