Overview

7 Interlude one: basic category theory for programmers

This interlude introduces category theory as a way to think about programming at an even higher level of abstraction. The chapter frames software development as the construction and composition of abstractions, then presents category theory as the study of relationships between “stuff,” where the stuff can be anything: numbers, people, types, or even categories. A category is described as a collection of objects plus morphisms, which are arrow-like relationships between objects. Morphisms must include an identity arrow for every object and must be transitive: if you can get from one object to a second, and from the second to a third, then you can get from the first to the third.

The chapter then explains functors as functions between categories that preserve morphisms. A covariant functor maps objects from one category to another while keeping the direction and structure of the morphisms intact. When such a functor maps a category to itself, it is called an endofunctor. These ideas are connected to programming language type systems by treating types as objects in a category and assignment compatibility as the morphism: for example, a value of type Giraffe can be assigned to a variable of type Animal, so there is a morphism from Giraffe to Animal. Under this view, a generic interface such as IEnumerable<T> is covariant when the mapping from T to IEnumerable<T> preserves those assignment-compatibility arrows.

The chapter also explains contravariance through interfaces that consume values rather than produce them, such as a comparer. An object that can compare any two animals can also compare any two giraffes, so an IC<Animal> can be used where an IC<Giraffe> is required. In category-theory terms, the mapping from T to IC<T> preserves the existence of morphisms but reverses their direction, making it a contravariant functor. The main takeaway is that language-design terms such as covariance and contravariance come directly from category theory, and that these abstract ideas help explain practical rules in modern type systems.

A small category with three objects, represented by the nodes, and six morphisms, represented by the arrows.
A strangely familiar small category with four objects and ten morphisms.
The function F is represented as dashed arrows mapping from one category to another
The category of four types with the assignment compatibility morphism; the identity morphisms are elided for clarity. Note that both Giraffe and Tiger have morphisms to Animal but not to each other. A Giraffe can’t be assigned to a variable of type Tiger and a Tiger can’t be assigned to a variable of type Giraffe, but both can be assigned to a variable of type Animal or Object.
Adding four constructed generic types to our category. Notice how the structure of the morphisms of the interface types looks very similar to that of the original four types.
The mapping of a function from types to types, shown as dashed arrows.
Part of another infinite category of types, this time with a contravariant interface.

Summary

  • Category theory is a modern mathematical discipline that studies relationships between arbitrary objects. It’s cheekily characterized as “generalized abstract nonsense”.
  • A category is a collection of objects that have reflexive, transitive morphisms; we can think of a morphism as an arrow going from one object to another.
  • A function that maps objects of one category to another such that morphisms are preserved is a covariant functor. One that preserves but reverses morphisms is a contravariant functor. If the two categories are the same, it is an endofunctor.
  • The assignment compatibility relation “an expression of type X may be assigned to a variable of type Y” is a common morphism on a category where types are objects.
  • Covariant and contravariant interfaces are called that because generic interfaces can be thought of as covariant or contravariant functors: functions from types to types that preserve assignment compatibility morphisms.
  • Posetal categories, that define a partial order on a set of objects, are common and particularly useful when objects are types in a programming language. Semilattices are posets that have the additional nice property that you can always find the most specific type that is assignment compatible with any two types.
  • The relationship between category theory and analysis of programming languages is very deep; we’ve just scratched the surface. We’ll go a little deeper in subsequent interludes.

FAQ

What is category theory, and why is it jokingly called “generalized abstract nonsense”?Category theory is a branch of mathematics that studies relationships between things rather than focusing on particular things like numbers. The “stuff” being related can be almost anything: numbers, sets, people, types in a programming language, or even categories themselves. Because it is highly abstract and general, category theorists jokingly call it “generalized abstract nonsense.”
Why is category theory useful to programmers?Programming is largely about creating abstractions and composing smaller solutions into larger ones. Category theory studies composable relationships and operations, so its ideas can help programmers recognize design patterns, reason about type systems, and better understand how programming language features are structured.
What is a category?A category consists of objects and morphisms. The objects can be anything. The morphisms are arrows connecting objects, representing some relationship such as “can get from here to there” or “can be assigned to.” Morphisms must obey two rules: every object has an identity morphism to itself, and morphisms are transitive.
What are morphisms?Morphisms are arrows between objects in a category. They represent a relationship chosen for that category. For example, in a category of types, a morphism from type X to type Y might mean that an expression of type X can be assigned to a variable of type Y. Morphisms are reflexive and transitive.
What does it mean for morphisms to be reflexive and transitive?Reflexive means every object has an identity morphism pointing to itself. If X is an object, then X → X is always a morphism. Transitive means that if A → B and B → C are morphisms, then A → C must also be a morphism.
What is a posetal category?A posetal category is a category whose morphisms are based on a partial ordering relationship, such as “greater than or equal to,” “is an ancestor of,” or “is assignable to.” In the chapter’s type example, Giraffe and Tiger both point to Animal, and Animal points to Object, but Giraffe and Tiger do not point to each other.
What is a functor?A functor is a function that maps objects from one category to objects in another category while preserving morphisms. If there is a morphism X → Y in the first category, a covariant functor F ensures there is also a morphism F(X) → F(Y) in the second category.
What is an endofunctor?An endofunctor is a functor that maps objects from a category back into the same category. In programming-language type systems, a generic type constructor such as mapping T to IE<T> can be understood as an endofunctor in the category of types, provided it applies to all relevant types and preserves morphisms.
Why is IEnumerable<T> or IE<T> called covariant?IE<T> is covariant because if a Giraffe can be assigned to an Animal, then IE<Giraffe> can also be assigned to IE<Animal>. The assignment relationship moves in the same direction before and after applying the generic type constructor. In C#, this is expressed with the out modifier, as in interface IE<out T>.
What does contravariance mean in the category-of-types example?Contravariance means the existence of morphisms is preserved, but their direction is reversed. For example, if Giraffe can be assigned to Animal, then an animal-comparer IC<Animal> can be assigned to a giraffe-comparer IC<Giraffe>. In C#, this is expressed with the in modifier, as in interface IC<in T>.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free