Foundations
Type Theory
Types as propositions, terms as proofs. Simply typed lambda calculus, the Curry-Howard correspondence, dependent types, and connections to programming language foundations and formal verification.
Prerequisites
Why This Matters
Type theory provides a single framework where programs and proofs are the same objects. A type is a specification; a term inhabiting that type is a program meeting that specification (or equivalently, a proof of the corresponding proposition). This is the Curry-Howard correspondence, and it is the foundation of modern proof assistants (Lean, Coq, Agda) and the theoretical basis for type systems in programming languages.
For ML researchers, type theory matters in two ways. First, formal verification of ML systems (proving correctness of gradient computations, verifying properties of neural network architectures) requires a logic powerful enough to express quantitative statements, and dependent type theory provides this. Second, the structure of type systems (polymorphism, higher-order types, linear types) directly influences the design of probabilistic programming languages used for Bayesian inference.
Simply Typed Lambda Calculus
Simple Types
The simple types over a set of base types are generated by the grammar:
Here is a base type (e.g., , ) and is the function type: the type of functions taking input of type and returning output of type . The arrow associates to the right: means .
Simply Typed Lambda Calculus
The simply typed lambda calculus () extends the untyped lambda calculus with type annotations. Terms are:
A typing judgment states that term has type under context (a mapping from variables to types). The typing rules are:
- Variable: If , then
- Abstraction: If , then
- Application: If and , then
Type Safety (Progress and Preservation)
A type system is safe if it satisfies two properties:
- Progress: If (closed, well-typed term), then either is a value or steps to some .
- Preservation (Subject Reduction): If and , then .
Together, these guarantee that well-typed programs do not get "stuck" (reach a state that is neither a value nor reducible).
The Curry-Howard Correspondence
Curry-Howard Correspondence
Statement
There is an exact correspondence between the simply typed lambda calculus and intuitionistic propositional logic:
| Type Theory | Logic |
|---|---|
| Type | Proposition |
| Term | Proof of |
| Function type | Implication |
| Lambda abstraction | Implication introduction (assume , derive ) |
| Function application | Modus ponens ( and yield ) |
| Inhabited type | Provable proposition |
| Type checking | Proof verification |
| Type inference | Proof search |
A proposition is provable in intuitionistic logic if and only if the corresponding type is inhabited (has a closed term of that type) in .
Intuition
Building a term of type means writing a function that takes an and returns a . In logic, this is the same as assuming and deriving , which is exactly an implication proof. The correspondence is not a metaphor; it is a formal isomorphism between two independently developed systems.
Proof Sketch
By structural induction on typing derivations and proof trees. Each typing rule corresponds to a proof rule:
- The variable rule corresponds to using an assumption from the context.
- The abstraction rule corresponds exactly to implication introduction .
- The application rule corresponds to modus ponens.
This bijection extends to normalization: beta-reduction of terms corresponds to cut-elimination in the proof system.
Why It Matters
The Curry-Howard correspondence means that type checkers are proof checkers. When Lean verifies that a term has a given type, it is verifying a mathematical proof. This unification is the reason proof assistants work: you write proofs as programs, and the type checker verifies them automatically. It also means that any advance in type theory yields an advance in logic, and vice versa. The correspondence extends further through category theory, where types correspond to objects, functions to morphisms, and the entire structure forms a cartesian closed category.
Failure Mode
The simple Curry-Howard correspondence covers only intuitionistic propositional logic (implications). To handle quantifiers ("for all", "there exists"), you need dependent types. To handle classical logic (law of excluded middle), you need control operators (continuations). The basic correspondence does not cover these extensions without additional machinery.
System F: Polymorphism
System F (Polymorphic Lambda Calculus)
System F extends with type variables and universal quantification over types:
Terms gain type abstraction and type application:
The polymorphic identity function has type and is written . Applying it to a specific type, say , yields .
Under Curry-Howard, corresponds to second-order universal quantification over propositions.
System F is strictly more expressive than . It can encode natural numbers, booleans, pairs, and lists purely through polymorphism, without built-in data types. The Church numeral has type , representing "apply a function times."
A critical property: type inference in System F is undecidable (Wells, 1999). Languages like Haskell and ML use restricted variants (Hindley-Milner, System F with rank-1 polymorphism) where type inference is decidable and runs in near-linear time.
Type Checking vs. Type Inference
Type Checking vs. Type Inference
Type checking is the problem: given , , and , decide whether .
Type inference is the problem: given and (with some type annotations possibly omitted), find a type such that , or report that none exists.
Type inference is strictly harder than type checking. For , both are decidable. For System F, type checking is decidable but type inference is undecidable. For dependently typed systems, type checking is decidable (given enough annotations) but type inference is generally undecidable.
Toward Dependent Types
In and System F, types cannot mention values. You can write the type "list of natural numbers" but not "list of natural numbers of length 5." Dependent type theory lifts this restriction:
- Pi types : the type of functions where the output type depends on the input value. This generalizes (where does not depend on ).
- Sigma types : the type of pairs where and . This generalizes .
Under Curry-Howard, corresponds to and corresponds to .
Practical Systems
| System | Types | Logic | Examples |
|---|---|---|---|
| Simple types | Propositional logic | Theoretical foundation | |
| Hindley-Milner | Rank-1 polymorphism | Restricted second-order | Haskell, OCaml, ML |
| System F | Full polymorphism | Second-order logic | Theoretical, GHC Core |
| System | Higher-kinded types | Higher-order logic | Haskell (partially) |
| CIC | Full dependent types | Higher-order predicate logic | Coq |
| MLTT | Full dependent types | Constructive type theory | Agda, Lean |
Common Confusions
Types in programming vs. types in type theory
In most programming languages, types are a safety mechanism: they prevent adding a string to an integer. In type theory, types are propositions and carry logical content. The type does not just prevent misuse; it states that the vector has exactly components, and a term of that type is evidence of this fact. Programming language types are a degenerate case of the full type-theoretic picture.
Intuitionistic vs. classical logic
The Curry-Howard correspondence gives intuitionistic logic, not classical logic. In intuitionistic logic, the law of excluded middle () is not provable, and there is no term of type in plain . This is because a proof of would require either a proof of or a proof of , with no "middle ground" allowed. Classical logic corresponds to lambda calculus extended with control operators (call/cc), which is a non-trivial extension.
Decidability of type checking depends on the system
Type checking for is decidable in polynomial time. Type checking for System F is decidable but type inference is not. Type checking for dependent types requires term normalization, so it is decidable only if the type theory is strongly normalizing (all well-typed terms terminate). If you add general recursion to a dependent type theory, type checking becomes undecidable.
Exercises
Problem
Write a term of type in the simply typed lambda calculus. What logical tautology does this type represent?
Problem
Prove that the type is inhabited in , where is defined as . Then explain why is not inhabited.
Problem
In System F, the Church encoding of natural numbers is . Write the terms for zero, successor, and addition, and verify their types.
Problem
Explain why type inference for System F is undecidable, while type inference for the Hindley-Milner system (used in Haskell and ML) is decidable. What restriction does Hindley-Milner impose?
References
Canonical:
- Girard, Lafont, Taylor, Proofs and Types (1989), Chapters 1-11
- Pierce, Types and Programming Languages (2002), Chapters 9-11 (simply typed), 23-25 (System F)
Additional:
- Sorensen and Urzyczyn, Lectures on the Curry-Howard Isomorphism (2006), Chapters 1-8
- Barendregt, "Lambda Calculi with Types" in Handbook of Logic in Computer Science (1992), Volume 2
Connection to proof assistants:
- The Coq Development Team, The Coq Reference Manual (2024), Chapter 4 (CIC)
- de Moura and Ullrich, "The Lean 4 Theorem Prover and Programming Language" (CADE 2021)
Next Topics
- Proof theory and cut elimination: the logical side of the Curry-Howard correspondence, where normalization of proofs corresponds to computation
- Dependent type theory: the full extension where types can depend on values, enabling the encoding of mathematical theorems
Last reviewed: April 2026
Prerequisites
Foundations this topic depends on.
- Lambda CalculusLayer 0A
- Basic Logic and Proof TechniquesLayer 0A