definition example theorem proof program

Let be functors. A natural transformation consists of, for each object , a morphism in (the -component), such that for every in the naturality square commutes:

F(c)G(c)F(d)G(d)®cF(f)G(f)®dF(c)G(c)F(d)G(d)®cF(f)G(f)®d

If every component is an Isomorphism, is a natural isomorphism (Natural Isomorphism). “A natural transformation maps objects to arrows, and arrows to commuting squares” (DaoFP). Kittenlab: a natural transformation “really lives in ” — the standard picture of floating between and hides this asymmetry.

Sources: 7 Sketches Definition 3.49, Examples 3.52, 3.53, 3.57, Exercises 3.55, 3.58, 3.64, §3.3.5; Kittenlab Lecture 6 (graph homomorphisms as a preview), 7; DaoFP §3.2 (“Naturality”), Chapter 9 (§9.1–9.3), §20.3 (enriched version). Related: Functor Category, Graph Homomorphism, Yoneda Lemma; CTfS §4.3 (Definition 4.3.1.1, Application 4.3.1.2, Examples 4.3.1.4–4.3.1.12, Proposition 4.3.2.2, Example 4.3.2.15, Definitions 4.3.2.16–4.3.2.17, Theorem 4.3.2.19), Example 4.5.3.22

Examples

  • Graph homomorphisms (7 Sketches §3.3.5, Kittenlab Lectures 6–7): for graphs , a natural transformation is a pair , and naturality for and says exactly “alpha-then-source equals source-then-alpha”: sources and targets are preserved. Likewise for Petri nets (arcs preserved) and any C-Set — “the naturality condition is very… natural”. 7S Exercise 3.64 computes one by hand.
  • Between sets viewed as functors , a natural transformation is just a function (Example 3.53).
  • Example 3.52: given , the components must be chosen so the one square commutes; “relates two views of inside “.
  • Preorders: between monotone maps (non-decreasing sequences) a natural transformation exists iff for all , and is unique; so is a preorder (Example 3.57; Kittenlab Lecture 7 for ). Into a preorder there is at most one natural transformation between any two functors; out of a preorder there may be many (7S Exercise 3.58).
  • Groups: between homomorphisms , a natural transformation is with — conjugation (Kittenlab Lecture 7).
  • , , the singleton list into the Free Monoid; naturality says mapping over equals (Kittenlab Lecture 7) — the unit of the Free-Forgetful Adjunction and of the List Monad.
  • Programming (DaoFP §9.3): a natural transformation between endofunctors of is a parametrically polymorphic function forall a. f a -> g a, e.g. safeHead :: [a] -> Maybe a, reverse :: [a] -> [a]. Parametricity makes naturality automatic (“theorems for free”), so fmap h . alpha = alpha . fmap h can be used to transform programs. Intuition: fmap transforms the contents of a container, a natural transformation repackages contents into another container without inspecting them; naturality says the two operations commute. (Filtering is not natural: it inspects the data.)
  • The unit and counit , of an Adjunction; the multiplication of a Monad; cones and cocones (DaoFP §9.4–9.5: cospans are natural transformations ).

Natural transformations as refinement of models (Category Theory for Scientists)

Application 4.3.1.2. A Finite State Machine on the alphabet is a functor . Your model has 3 states; a collaborator proposes a refined model with 6 states that is “compatible”. Compatibility is a natural transformation — here merging States 1A, 1B, 1C into State 1 and 2A, 2B into State 2:

01A2A012
1A2A1B121
1B2B1C200
1C2B1B
2A00
2B00

The monoid has one object, so has a single component , and only the two naturality squares for the generators and need checking (longer words follow by pasting squares): e.g. . “It is quite convenient to simply claim: there is a natural transformation from to .” Natural isomorphisms of state machines are relabelings of states (CTfS Exercise 4.3.2.13).

Adding a button (whiskering, CTfS Example 4.3.2.15). If the sequence is used a lot, add a button for it: a monoid homomorphism , , , . The same still works for the machines and : that is the whiskering .

Other CTfS examples: taking the source (or the target) of an arrow is a natural transformation from the arrow-set functor to the vertex-set functor (CTfS Exercise 4.3.1.11); every graph includes into its graph of paths, , and paths of paths concatenate, (CTfS Examples 4.3.1.5–4.3.1.6); a natural transformation is a commutative square (CTfS Example 4.3.1.4), and in general is a functor (CTfS Example 4.5.3.22). Historically, Eilenberg and Mac Lane invented categories to talk about natural transformations such as the Hurewicz map , which forgets the order in which loops are travelled.

Composition

  • Vertical composition (7S Exercise 3.55, DaoFP §9.3): for , , define (“for each object , compose the -components”); naturality follows by pasting two squares. The identity . This makes the Functor Category .
  • Horizontal composition (DaoFP §9.3): for () and (), , the two being equal by naturality of ; in Haskell beta . fmap alpha = fmap alpha . beta. Whiskering is horizontal composition with an identity: (just a change of type signature) and (fmap alpha); . The interchange law says vertical-then-horizontal equals horizontal-then-vertical. These make a 2-Category.

Enriched version (DaoFP §20.3)

In a -category there are no individual arrows, so a component is a “global element” , and naturality is a commuting hexagon built from , , and composition — equivalently . See Enriched Natural Transformation.

Docs: Categories & functors · C-set morphisms · ACSets API · Graphs — Kittenlab Lecture 6, Lecture 7

Builds on: Category (Category), Functor (Functor) — run those notes’ Julia code first.

# Kittenlab src/NaturalTransformations.jl
abstract type NaturalTransformation{C<:Category, D<:Category} end
# component(α::NaturalTransformation{C,D}, x::ObC)::HomD
 
struct FunctorCat{C<:Category, D<:Category} <: Category{Functor{C,D}, NaturalTransformation{C,D}}
  c::C; d::D
end
struct ComposedNT{C,D,A<:NaturalTransformation{C,D},B<:NaturalTransformation{C,D}} <: NaturalTransformation{C,D}
  cats::FunctorCat{C,D}; α::A; β::B
end
component(γ::ComposedNT, x) = compose(γ.cats.d, component(γ.α, x), component(γ.β, x))   # vertical composition
struct IdTransformation{C,D} <: NaturalTransformation{C,D}
  f::Functor{C,D}
end
Categories.id(::FunctorCat, f::Functor) = IdTransformation(f)

Catlab version (run in a fresh Julia session — Catlab exports its own compose, id, FinFunction, …):

# Catlab: natural transformations between C-sets = ACSet transformations (graph homomorphisms)
using Catlab
G = @acset Graph begin V = 3; E = 2; src = [1, 2]; tgt = [2, 3] end          # Example 3.63
H = @acset Graph begin V = 2; E = 3; src = [1, 1, 2]; tgt = [2, 2, 2] end
α = ACSetTransformation(G, H; V = [1, 2, 2], E = [2, 3])                       # Exercise 3.64: a ↦ d, b ↦ e
is_natural(α)                       # true: the naturality squares for src and tgt commute
homomorphisms(G, H)                 # all graph homomorphisms, by search
#check CategoryTheory.NatTrans      -- structure NatTrans F G: app, naturality; notation F ⟶ G in C ⥤ D
open CategoryTheory in
example {C D : Type} [Category C] [Category D] (F G : C ⥤ D) (α : F ⟶ G) {X Y : C} (f : X ⟶ Y) :
    F.map f ≫ α.app Y = α.app X ≫ G.map f := α.naturality f
#check @CategoryTheory.NatTrans.vcomp
#check @CategoryTheory.NatTrans.hcomp
#check CategoryTheory.NatIso        -- natural isomorphisms F ≅ G
{-# LANGUAGE RankNTypes #-}
-- DaoFP §9.3: a natural transformation is a parametrically polymorphic function
type Natural f g = forall a. f a -> g a
 
safeHead :: Natural [] Maybe
safeHead []      = Nothing
safeHead (a : _) = Just a
 
-- naturality (free by parametricity):  fmap h . safeHead == safeHead . fmap h
 
-- vertical composition is function composition; horizontal composition:
hcomp :: (Functor g) => Natural g g' -> Natural f f' -> (forall x. g (f x) -> g' (f' x))
hcomp beta alpha = beta . fmap alpha