definition example program

A sum type is the Coproduct of two types, seen from the programmer’s side: it is defined by two arrows, the data constructors and (the introduction rule), together with the elimination rule: a mapping out is the same as a pair of arrows , , with and (the computation rules). In Haskell the sum is Either a b; the elimination rule is pattern matching.

aba+bcLeftfRightghaba+bcLeftfRightgh

Sources: DaoFP Chapter 4 (“Sum Types”: §4.1 “Bool”, §4.2 “Enumerations”, §4.3 “Sum Types”, “Maybe”, “Logic”, §4.4 “Cocartesian Categories”), §6.1 (either, unEither, bimap), §5.2 (“Duality”); 7 Sketches §6.2.2; Kittenlab Lecture 11 (coproducts of types in Julia).

Instances

  • Bool : two constructors True, False :: Bool (arrows from ); a function Bool -> A is the same as a pair of elements of A, written if b then x else y. So there are functions , function and functions — the counts of exponentials (DaoFP Exercise 4.1.1). See Booleans.
  • Enumerations: data RGB = Red | Green | Blue is ; a function out of it is a triple of elements, written by pattern matching or case; the wildcard _ matches everything else. Char, Int, Double are (huge) enumerations; Integer is genuinely infinite.
  • Maybe : data Maybe a = Nothing | Just a, isomorphic to Either () a; used for partial functions instead of exceptions.
  • Logic: is disjunction; to prove from one must handle both cases — exactly the two arrows of the elimination rule (Curry–Howard).
  • Recursive sums: () and lists ().

Cocartesian categories

A category with all binary sums and an Initial Object is cocartesian. Using the Yoneda trick (compare mappings out of both sides, naturally in the target) one shows , (DaoFP Exercise 4.4.1), (DaoFP Exercise 4.4.2, DaoFP Exercise 4.4.3) and , and is functorial: preserves composition and identities (DaoFP Exercise 4.4.4, DaoFP Exercise 4.4.5). Hence is a Symmetric Monoidal Category (same content as 7S Exercise 6.18). “When a child learns addition we call it arithmetic. When a grownup learns addition we call it a cocartesian category.” The dual notion is a Cartesian Category.

Docs: FinSets · Limits & colimits — Kittenlab Lecture 11

using Catlab
# sums of finite sets are coproducts; copairing implements the elimination rule
A = FinSet(2); B = FinSet(3)
S = coproduct(A, B)                     # A + B = FinSet(5), with coproj1, coproj2 (Left, Right)
f = FinFunction([1, 1], 2); g = FinFunction([2, 2, 1], 2)
h = copair(S, f, g)                     # [f, g] : 5 → 2
compose(coproj1(S), h) == f             # computation rule
 
# Julia's own sum types are Union{} / tagged structs; pattern matching by dispatch
either(f, g, x::Union{Some, Nothing}) = x === nothing ? g() : f(something(x))
import Mathlib
#check @Sum                    -- α ⊕ β with Sum.inl, Sum.inr
#check @Sum.elim               -- (α → γ) → (β → γ) → α ⊕ β → γ   (elimination rule)
#check @Sum.elim_inl           -- computation rule
#check @Equiv.sumComm          -- α ⊕ β ≃ β ⊕ α
#check @Equiv.sumAssoc
#check @Equiv.sumEmpty         -- α ⊕ Empty ≃ α
#check @Bool.rec               -- the recursor for 2 = 1 + 1
data Either a b where          -- introduction rules
  Left  :: a -> Either a b
  Right :: b -> Either a b
 
either :: (a -> c) -> (b -> c) -> Either a b -> c    -- elimination rule
either f _ (Left x)  = f x
either _ g (Right y) = g y
 
unEither :: (Either a b -> c) -> (a -> c, b -> c)     -- the other direction of the bijection
unEither h = (h . Left, h . Right)
 
data Maybe a = Nothing | Just a                       -- 1 + a
notB :: Bool -> Bool
notB b = if b then False else True