definition example

A category consists of the following data:

  1. A collection of objects (“collection”: a bunch of things like a set, but possibly too large to be a set — e.g. all sets, cf. Russell’s paradox)
  2. For each pair of objects , a set (also , the hom-set; “hom” for homomorphism) of morphisms (or arrows) from to , written ; is the domain and the codomain
  3. For each object , an identity morphism
  4. For each triple of objects , a composition operation written — or, in the diagrammatic order preferred by 7 Sketches and Catlab, (” then ”)

subject to the following axioms:

Associativity: For all morphisms , , ,

Identity (unitality): For all morphisms ,

Sources: 7 Sketches Definition 3.6 (§3.2); Kittenlab Lecture 3 (“small category”); DaoFP §1–2, §8.1. The 7 Sketches motto: structure (objects, morphisms, composition) plus coherence (associativity, unitality) — “a chain of chains is itself a long chain”.


Examples

Three viewpoints

  • 7 Sketches (databases). A category is a schema: objects are tables, morphisms are columns/foreign keys, and path equations are business rules; the data is a Functor .
  • Kittenlab (computation). A small category has a set of objects and sets ; in Julia a category is a value of a type Category{Ob,Hom} with dom, codom, compose, id — a “middle path” where types guide dispatch but are not relied on for correctness.
  • DaoFP (programming). Objects are types (or propositions), arrows are functions (or implications/entailments) — the Curry–Howard–Lambek correspondence. “Programming is about composition”; an object is defined by its connections (“things are defined by their relationship to the Universe”); we compare arrows for equality but objects only up to Isomorphism (equality of objects is “evil”).

Type-Theoretic Formulation

A category may be encoded as a dependent type with the following signature:


Commutative Diagram

The associativity and identity axioms are expressed by the commutativity of:

XYWZfg±fgh±ghXYWZfg±fgh±gh
XYXYffidXidYfXYXYffidXidYf

Functor (maps between categories), Natural Transformation (maps between functors), Isomorphism, Monomorphism, Epimorphism, Terminal Object, Initial Object, Product, Coproduct, Limit, Colimit, Adjunction, Yoneda Lemma, Monoidal Category, 2-Category. Universal constructions: “one gives some specified shape in a category and says find me the best solution!” (7 Sketches §3.6).

Docs: FinSets · ThCategory (GATlab) · Theories & presentations — Kittenlab Lecture 3, Lecture 5 Kittenlab’s interface (a faithful copy of src/Categories.jl and src/FinSets.jl; runs on its own, and the other Kittenlab-style tabs of the vault build on it):

module Categories
export Category, dom, codom, compose, id
abstract type Category{Ob, Hom} end
function dom(c::Category{Ob,Hom}, f::Hom)::Ob where {Ob,Hom}; error("unimplemented"); end
function codom(c::Category{Ob,Hom}, f::Hom)::Ob where {Ob,Hom}; error("unimplemented"); end
function compose(c::Category{Ob,Hom}, f::Hom, g::Hom)::Hom where {Ob,Hom}; error("unimplemented"); end  # f then g
function id(c::Category{Ob,Hom}, x::Ob)::Hom where {Ob,Hom}; error("unimplemented"); end
# Laws (not enforced):
#   compose(c, f, compose(c, g, h)) == compose(c, compose(c, f, g), h)
#   compose(c, f, id(c, codom(c, f))) == f == compose(c, id(c, dom(c, f)), f)
end
using .Categories
 
# the category of finite sets and functions
struct FinFunction{S,T}
  dom::AbstractSet{S}; codom::AbstractSet{T}; values::Dict{S,T}
end
(f::FinFunction{S})(x::S) where {S} = f.values[x]
struct FinSetC <: Category{AbstractSet, FinFunction} end
Categories.dom(::FinSetC, f::FinFunction) = f.dom
Categories.codom(::FinSetC, f::FinFunction) = f.codom
function Categories.compose(::FinSetC, f::FinFunction{S,T}, g::FinFunction{T,R}) where {S,T,R}
  @assert f.codom == g.dom
  FinFunction(f.dom, g.codom, Dict(x => g(f(x)) for x in f.dom))
end
Categories.id(::FinSetC, X::AbstractSet{S}) where {S} = FinFunction{S,S}(X, X, Dict(x => x for x in X))
 
let A = Set([:x, :y, :z]), B = Set([1, 3, 4])          # (a `let`, so notes building on this one can reuse the names)
  f = FinFunction(A, B, Dict(:x => 3, :y => 1, :z => 1))
  compose(FinSetC(), id(FinSetC(), A), f).values == f.values   # unitality: true
end

Catlab (a separate session — Catlab exports its own Category, compose, id): the generalized algebraic theory of categories and a free category on generators.

using Catlab
@present C(FreeCategory) begin
  (X, Y, Z)::Ob
  f::Hom(X, Y); g::Hom(Y, Z)
end
compose(C[:f], C[:g])           # f ⋅ g : X → Z
id(C[:X]) ⋅ C[:f] == C[:f]      # unitality holds in the free category
-- Mathlib: CategoryTheory.Category
class Category (C : Type u) extends CategoryStruct C where   -- Hom, 𝟙, ≫ (diagrammatic order)
  id_comp : ∀ {X Y : C} (f : X ⟶ Y), 𝟙 X ≫ f = f
  comp_id : ∀ {X Y : C} (f : X ⟶ Y), f ≫ 𝟙 Y = f
  assoc : ∀ {W X Y Z : C} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z), (f ≫ g) ≫ h = f ≫ g ≫ h
 
open CategoryTheory in
example : Category (Type u) := inferInstance          -- Set
open CategoryTheory in
example {α : Type} [Preorder α] : Category α := inferInstance   -- a preorder as a thin category
import Prelude hiding (id, (.))
 
class Category cat where
  id  :: cat a a
  (.) :: cat b c -> cat a b -> cat a c
  -- Laws (not enforceable):
  -- id . f = f;  f . id = f;  (h . g) . f = h . (g . f)
 
-- DaoFP: the category of types and functions
instance Category (->) where
  id = \x -> x
  g . f = \x -> g (f x)