← back to index

Function Types

Bartosz Milewski Β· 2015 Β· Category Theory for Programmers, Ch. 9

Prereqs: 🍞 Ch5 (Products and Coproducts), 🍞 Ch7 (Functors). 10 min.

A function type a β†’ b is not just a mapping. It is an object in the category, called the exponential ba. Currying is the adjunction between products and exponentials: (a Γ— b) β†’ c β‰… a β†’ (b β†’ c). This isomorphism is why every multi-argument function is secretly a chain of single-argument functions.

Universal construction of function objects

In Set, the set of all functions from a to b is itself a set (the hom-set). In an arbitrary category, there is no guarantee that morphisms between two objects form an object in the same category. The exponential object ba is defined by a universal construction: it comes equipped with an eval morphism from ba Γ— a to b, and any other candidate factors through it uniquely.

Scheme
A × B C f A B → C g uncurried curried curry / uncurry are inverses

Currying: the adjunction

Currying is the heart of this chapter. A function of two arguments (a Γ— b) β†’ c can always be rewritten as a function that takes one argument and returns a function: a β†’ (b β†’ c). This is a natural isomorphism: the two forms carry the same information.

Scheme

The isomorphism: (a Γ— b) β†’ c β‰… a β†’ (b β†’ c)

Curry and uncurry are inverses. This means the set of functions from a product is isomorphic to the set of higher-order functions. In exponential notation: c(aΓ—b) β‰… (cb)a. This is the familiar law of exponents: xyz = (xy)z. The algebraic identity is not an analogy. It is the same identity, living in the category.

Scheme

Why "exponentials"?

The notation is not metaphorical. For finite sets, the number of functions from a to b is literally |b||a|. A function from a 3-element set to a 2-element set must make 3 independent binary choices, giving 23 = 8 possible functions. The algebraic laws of exponents hold exactly because they are the algebraic laws of function types.

Scheme

Cartesian closed categories

A category where you can always form products and exponentials is called Cartesian closed. It must have three things: a terminal object (the empty product), a product for every pair of objects, and an exponential for every pair of objects. Set is the canonical example. So is every typed lambda calculus. A Cartesian closed category is exactly the categorical semantics of a language with functions and tuples.

Scheme

Algebraic laws of exponentials

In a bicartesian closed category (one that also has coproducts), the laws of high-school algebra hold for types. Sums are addition, products are multiplication, exponentials are exponentiation, and the distributive law connects them. These are not analogies. They are isomorphisms between types.

Scheme

Curry-Howard: functions as proofs

Under the Curry-Howard correspondence, the function type a β†’ b is logical implication: "if a then b." The eval morphism proves modus ponens: given (a β‡’ b) and a, produce b. Currying proves the deduction theorem: to prove a β‡’ (b β‡’ c), assume a and b, then prove c. Cartesian closed categories constrain what compositions are physically realizable β€” jktype forcing shows how physical constraints collapse Spivak's operad of possible wirings down to the ones that actually typecheck.

Scheme

Notation reference

Blog / Haskell Scheme Meaning
a β‡’ b / ba(lambda (x) ...)Exponential object / function type
eval :: (a⇒b, a) → b(my-eval (cons f x))Function application as a morphism
curry f a b = f (a, b)(my-curry f)Product argument β†’ higher-order function
uncurry f (a,b) = f a b(my-uncurry g)Higher-order function β†’ product argument
CCCβ€”Cartesian closed category: terminal + products + exponentials
a β†’ b (Curry-Howard)(lambda ...)Logical implication / proof
Neighbors

Milewski chapters

  • 🍞 Chapter 8 β€” Functoriality: bifunctors, contravariance, profunctors
  • (next) Chapter 10 β€” Natural Transformations: polymorphic functions

Paper pages that use these concepts

Foundations (Wikipedia)

Translation notes

The blog post uses Haskell's native currying (all functions are curried by default) and C++ templates. This page makes currying explicit with my-curry and my-uncurry, since Scheme's lambda can take multiple arguments. The universal construction of exponentials is presented informally here. In the blog post, Milewski gives the full pattern: a candidate is a pair (z, g : z Γ— a β†’ b), the ranking says z is better than z' when there exists h : z' β†’ z such that g' = g ∘ (h Γ— id), and the exponential ba is the universal (best) such candidate. The eval morphism is not just function application dressed up in categorical language. It is the counit of the product-exponential adjunction, which Chapter 16 covers in full.

Ready for the real thing? Read the blog post. Start with the universal construction, then trace how the exponential laws recover high-school algebra.