Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/teaching/nprg077
LCF theorem prover
ML used for writing
meta-programs to generate proofs
Types used to ensure
the validity of proofs
Given a typing context \(\Gamma\), the
expression \(e\) has a type \(\tau\)
We know some of these,
want to figure out the rest
Best type of
an expression
Any other type of the expression is a special case (subtype) of it
Generate constraints
Recursively over expression
Solve constraints
Recursively over constraint set
In the "Algorithm W", the two are combined. We separate them!
(* Basic types with
type variables *)
type Type =
| TyNumber
| TyVariable of string
| TyFunction of Type * Type
| TyList of Type
(* Constraint specifies
that one type should be
unified with another *)
type Constraint =
Type * Type
A pair of types that
should be unified
Easy or impossible
int = int -> int
int list = int list
Tricky with variables
'a = int -> 'b
'a = 'c -> int
Zero
, Succ(x)
Succ(x) = Succ(Succ(Zero))
Substitution (#1) Replace variable in remaining constraints
Substitution (#2)
Apply substitutions
to assigned type
Occurs check (#3) Check for unsolvable constraints
(* All possible types you may
support: type variables,
primitives and composed *)
type Type =
| TyVariable of string
| TyBool
| TyUnit
| TyNumber
| TyFunction of Type * Type
| TyTuple of Type * Type
| TyUnion of Type * Type
| TyList of Type
| TyForall of string * Type
(* Types of known variables *)
type TypingContext =
Map<string, Type>
Type variables
For constraint solving!
Primitive types
Match/mismatch
Composed types
Generate one or two new constraints
Polymorphic type
Forall (bonus)
(* Given a list of
constraints, produce a
list of substitutions *)
val solve :
list<Type * Type>
-> list<string * Type>
(* Given a typing context
(known variables) and
expression, return the type
of the expression and
list of constraints *)
val generate :
TypingContext
-> Expression
-> Type * list<Type * Type>
Constraint solving
Takes constraints
Produces substitution
Constraint generating
Takes an expression
Produces constraints
Also check variables
Complete the simple numerical constraint solver
Add the two missing substitutions to make it work!
Solving type constraints with numbers and Booleans
Follow the same structure, but now for type constraints...
Type inference for binary operators and conditionals
Add constraint generation for a subset of TinyML
Supporting more TinyML expressions
Add let, functions, application and occurs check
Adding simple data types
Constraint generation for tuples
Supporting more TinyML data types
Add type checking for discriminated unions
Type inference for lists - poor method
Add recursion & units and try this on list code!
Adding proper support for generic lists
New type, but without explicit type declarations
Inferring polymorphic code for let bindings
Implementing proper Hindley-Milner let-polymorphism
Exploring pathological cases
Did you know HM has DEXPTIME complexity?
Tiny Hindley-Milner type inference
Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/teaching/nprg077