---
layout: default
file: "src/Setoid/Categories/Functor.lagda.md"
title: "Setoid.Categories.Functor module"
date: "2026-06-08"
author: "the agda-algebras development team"
---

### Functors between minimal categories

This is the [Setoid.Categories.Functor][] module of the [Agda Universal Algebra Library][].

A *functor* is a structure-preserving translation between categories โ€” the
categorical analog of a homomorphism.  Where a homomorphism of algebras carries
elements to elements while preserving the operations, a `Functor ๐‚ ๐ƒ` carries the
*objects* of `๐‚` to objects of `๐ƒ` (the object map `Fโ‚€`{.AgdaField}) and the
*morphisms* of `๐‚` to morphisms of `๐ƒ` (the hom map `Fโ‚`{.AgdaField}), while
preserving the only structure a category has: identities and composition.  Those two
preservation conditions are the functor laws `identity`{.AgdaField} and
`homomorphism`{.AgdaField}, and โ€” as everywhere in this layer โ€” they are stated up to
the *target* category's hom-equality `_โ‰ˆ_`, so a category whose hom-equality is
pointwise can prove them pointwise, without function extensionality.

Why insist on the laws, rather than taking any pair of maps `(Fโ‚€ , Fโ‚)`?  Because the
laws are what make diagram-chasing arguments transport along `F`: a commuting diagram
in `๐‚` is a tower of composites, and `homomorphism` is exactly the license to push
`F` through each composite, corner by corner.  The third field, `F-resp-โ‰ˆ`{.AgdaField},
plays the same role for equational rewriting that `cong` plays for setoid functions:
it lets a proof replace a morphism by an equal one underneath `Fโ‚`.  (In a setting with
unique identity proofs `F-resp-โ‰ˆ` would be automatic; with hom-*setoids* it must be
data, just as `Func` must carry `cong`.)

The two running examples in this library are good ones to keep in mind:

+  `reductF ฯ†` ([Setoid.Categories.Reduct][]) translates the world of
   `๐‘†โ‚‚`-algebras into the world of `๐‘†โ‚`-algebras along a signature morphism `ฯ†`: the
   object map forgets (reindexes) operations, the hom map is the identity on the
   underlying setoid maps.
+  `adjoinUnitF` ([Classical.Categories.AdjoinUnit][]) translates semigroups into
   monoids by freely adjoining a unit: the object map genuinely *constructs* (it
   enlarges the carrier), and the hom map extends a homomorphism to the new element.

This module also provides the identity functor `idF`{.AgdaFunction} and functor
composition `_โˆ˜F_`{.AgdaFunction}.  They are what make "functor" a closed vocabulary โ€”
the composite of two translations is a translation โ€” and they are needed the moment a
construction must *name* a composite functor, as the [`Monad`][Setoid.Categories.Monad]
record does when it types its unit `Id โŸน T` and multiplication `T โˆ˜ T โŸน T`.

<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}

module Setoid.Categories.Functor where

open import Agda.Primitive  using ( _โŠ”_ ) renaming ( Set to Type )
open import Function           using ( id )
open import Level           using ( Level )

open import Setoid.Categories.Category using ( Category )

private variable
  o โ„“ e oโ€ฒ โ„“โ€ฒ eโ€ฒ oโ€ณ โ„“โ€ณ eโ€ณ : Level
```
-->

```agda
record Functor (๐‚ : Category o โ„“ e) (๐ƒ : Category oโ€ฒ โ„“โ€ฒ eโ€ฒ) : Type (o โŠ” โ„“ โŠ” e โŠ” oโ€ฒ โŠ” โ„“โ€ฒ โŠ” eโ€ฒ) where
  open Category ๐‚ renaming (Obj to ๐‚โ‚€; Hom to ๐‚[_,_]; _โ‰ˆ_ to _โ‰ˆแตˆแต’แต_; id to idแตˆแต’แต; _โˆ˜_ to _โˆ˜แตˆแต’แต_)
  open Category ๐ƒ renaming (Obj to ๐ƒโ‚€; Hom to ๐ƒ[_,_]; _โ‰ˆ_ to _โ‰ˆแถœแต’แตˆ_; id to idแถœแต’แตˆ; _โˆ˜_ to _โˆ˜แถœแต’แตˆ_)
  field
    Fโ‚€ : ๐‚โ‚€ โ†’ ๐ƒโ‚€
    Fโ‚ : {A B : ๐‚โ‚€} โ†’ ๐‚[ A , B ] โ†’ ๐ƒ[ Fโ‚€ A , Fโ‚€ B ]
    F-resp-โ‰ˆ : {A B : ๐‚โ‚€} {f g : ๐‚[ A , B ]} โ†’ f โ‰ˆแตˆแต’แต g โ†’ Fโ‚ f โ‰ˆแถœแต’แตˆ Fโ‚ g
    identity : {A : ๐‚โ‚€} โ†’ Fโ‚ (idแตˆแต’แต {A}) โ‰ˆแถœแต’แตˆ idแถœแต’แตˆ
    homomorphism : {A B E : ๐‚โ‚€} {f : ๐‚[ A , B ] } {g : ๐‚[ B , E ]} โ†’ Fโ‚ (g โˆ˜แตˆแต’แต f) โ‰ˆแถœแต’แตˆ Fโ‚ g โˆ˜แถœแต’แตˆ Fโ‚ f
```

#### The identity functor and composition of functors

The identity functor leaves objects and morphisms untouched; its laws are each
hom-setoid's reflexivity.

```agda
idF : {๐‚ : Category o โ„“ e} โ†’ Functor ๐‚ ๐‚
idF {๐‚ = ๐‚} = record  { Fโ‚€            = id
                      ; Fโ‚            = id
                      ; F-resp-โ‰ˆ      = id
                      ; identity      = โ‰ˆ-refl
                      ; homomorphism  = โ‰ˆ-refl
                      }
  where open Category ๐‚ using ( โ‰ˆ-refl )
```

Functors compose in the application order of their object maps: `(G โˆ˜F F)` first
applies `F`, then `G`, on objects and morphisms alike.  Each composite law unfolds to
"push the inner functor's law through the outer functor, then apply the outer
functor's law" โ€” one `F-resp-โ‰ˆ` followed by one `โ‰ˆ-trans`, a pattern worth noticing
because every composite-functor proof in this library has this shape.

```agda
infixr 9 _โˆ˜F_

_โˆ˜F_ : {๐‚ : Category o โ„“ e} {๐ƒ : Category oโ€ฒ โ„“โ€ฒ eโ€ฒ} {๐„ : Category oโ€ณ โ„“โ€ณ eโ€ณ}
  โ†’ Functor ๐ƒ ๐„ โ†’ Functor ๐‚ ๐ƒ โ†’ Functor ๐‚ ๐„
_โˆ˜F_ {๐„ = ๐„} G F = record
  { Fโ‚€            = ฮป A โ†’ G.Fโ‚€ (F.Fโ‚€ A)
  ; Fโ‚            = ฮป f โ†’ G.Fโ‚ (F.Fโ‚ f)
  ; F-resp-โ‰ˆ      = ฮป fโ‰ˆg โ†’ G.F-resp-โ‰ˆ (F.F-resp-โ‰ˆ fโ‰ˆg)
  ; identity      = โ‰ˆ-trans (G.F-resp-โ‰ˆ F.identity) G.identity
  ; homomorphism  = โ‰ˆ-trans (G.F-resp-โ‰ˆ F.homomorphism) G.homomorphism
  }
  where
  open Category ๐„ using ( โ‰ˆ-trans )
  module F = Functor F
  module G = Functor G
```