Proposition (CTfS 2.7.3.1). Writing for the Coproduct (disjoint union), for the Product, for the set of functions (Exponential Object), and , , there are isomorphisms, for all sets :
| addition | multiplication | exponentiation |
|---|---|---|
| , | , | |
| (for ), | ||
“One can think of the natural numbers as literally being the isomorphism classes of finite sets — that’s what they are used for in counting”: to count cows in a field is to build a bijection between the herd and (Cardinality). So the laws of arithmetic of are shadows of isomorphisms of sets; that multiplication distributes over addition “is a fact about grids of dots”.
Sources: CTfS §2.7.3 (Proposition 2.7.3.1, Exercises 2.7.3.2–2.7.3.3), §2.7.2 (Exercises 2.7.2.2, 2.7.2.6), Proposition 4.6.5.1 (the same laws for categories); DaoFP Chapters 4–6 (“tuple arithmetic”, “function types”, distributivity), §10.7; 7 Sketches §3.5; related: Categorification, Bicartesian Closed Category.
Why these hold — universal properties, not elements
Each isomorphism can be proved by exhibiting maps both ways, but the categorical proof compares maps out of (or into) both sides, which is why the same laws hold in every Bicartesian Closed Category:
- : a map out of a sum is a pair of maps (Coproduct, “if we know how economy seats and first-class seats are priced, we know how all seats are priced”).
- : Currying.
- : is a left adjoint, so it preserves coproducts (Right Adjoints Preserve Limits; CTfS Exercise 5.1.3.4).
- (the empty function), for (no functions into ), .
The one exception:
The table claims both for every and — which conflict at . Going back to the definitions settles it: has exactly one element, so (CTfS Exercise 2.7.3.2). This is why the hypothesis appears in .
Other consequences
- for finite sets, including the empty cases (CTfS Exercise 2.7.2.2); because (Power Set, Subobject Classifier).
- means both and ; they agree because and (CTfS Exercise 2.7.2.6).
- Zero divisors: as for numbers, forces or — a pair needs both components (CTfS Exercise 2.7.3.3).
- Categories (CTfS Proposition 4.6.5.1): with coproduct , product and functor categories , exactly the same laws hold in — “astoundingly” — e.g. , , (Functor Category). The same holds in any Topos, e.g. for database instances.
- Types: in Haskell
Either,(,),->,Void,()satisfy the table up to isomorphism — “algebraic data types” (DaoFP).
Docs: FinSets · Limits & colimits
using Catlab
A, B, C = FinSet(2), FinSet(3), FinSet(4)
# A × (B + C) ≅ A×B + A×C, checked on cardinalities of the (co)limits Catlab computes
length(apex(product(A, apex(coproduct(B, C))))) ==
length(apex(coproduct(apex(product(A, B)), apex(product(A, C))))) # 14 == 14
# |B^A| = |B|^|A|: enumerate all functions A → B as FinFunctions
functions(A, B) = [FinFunction(collect(v), B) for v in Iterators.product(fill(1:length(B), length(A))...)]
length(functions(A, B)) == length(B)^length(A) # 9
length(functions(FinSet(0), FinSet(0))) # 1 (0⁰ = 1)import Mathlib
-- the laws as explicit equivalences of types
#check @Equiv.sumComm -- α ⊕ β ≃ β ⊕ α
#check @Equiv.prodSumDistrib -- α × (β ⊕ γ) ≃ α × β ⊕ α × γ
#check @Equiv.sumArrowEquivProdArrow -- (α ⊕ β → γ) ≃ (α → γ) × (β → γ)
#check @Equiv.curry -- (α × β → γ) ≃ (α → β → γ)
#check @Equiv.emptyArrowEquivPUnit -- (Empty → α) ≃ PUnit (A⁰ ≅ 1)
#check @Fintype.card_fun -- card (α → β) = card β ^ card α
example : (0 : ℕ) ^ 0 = 1 := rflimport Data.Void (Void, absurd)
distrib :: (a, Either b c) -> Either (a, b) (a, c) -- A × (B + C) → A×B + A×C
distrib (a, Left b) = Left (a, b)
distrib (a, Right c) = Right (a, c)
expSum :: (Either b c -> a) -> (b -> a, c -> a) -- A^(B+C) → A^B × A^C
expSum h = (h . Left, h . Right)
expZero :: () -> (Void -> a) -- 1 → A^0: the empty function
expZero () = absurd