Title: Type inference
1- Lecture 27
- Type inference
- 2 Nov 05
2Type inference (reconstruction)
- Simple typed language
- e x b lxt . e e1 e2 e1 e2
- if e0 then e1 else e2 let xe1 in e2 rec
yt1t2.(lx.e) - unit bool int t1t2
- Question Do we really need to write type
declarations? - e lx.e rec y.(lx.e)
3Typing rules
- e x b lx.e e1 e2 e1 ? e2 if e0
then e1 else e2 let xe1 in e2 rec y.lx.e
Problem how does type checker construct
proof? Guess t, t? ?
4Example
- let square lz.zz in(lf.lx.ly. if (f x
y) then (f (square x) y) else (f x (f x y))) - What is the type of this program?
5Manual type inference
- let square lz.zz in(lf.lx.ly. if (f x
y) then (f (square x) y) else (f x (f x y))) - z int
- s, square intint
- f txtybool
- y ty bool
- x tx int
Answer (intboolbool)intboolbool
6Type inference
- Goal reconstruct types even after erasure
- Idea run ordinary type-checking algorithm,
generate type equations on type variables
fT2, xT5 ? f int T6 fT2, xT5 ? 1
int fT2, xT5 ? f 1 T6 fT2 ? lx. f 1 T1
(T5T6) yT3 ? y T4 ?lf. lx. f 1
T2T1 ?(ly.y) T2 (T2T3T4) ?(lf.lx. (f 1))
(ly.y) T1
(T3T4)
T2 T3T4, T3 T4, T1 T5T6, T2 intT6
7Typing rules
Only type metavariableson RHS of premises
8Unification
- How to solve equations?
- Idea given equation t1 t2, unify type
expressions to solve for variables in both - Example T1int (boolT2)T3
- Result substitution T1 ? boolT2, T3?int
9Robinsons algorithm (1965)
- Unification produces weakest substitution that
equates two trees - T1int (boolT2)T3 equated by anyT1?boolT2,
T3?int, T2?t - Defn. S1 is weaker than S2 if S2 S3?S1 for S3
a non-trivial substitution - Unify(E) where E is set of equations gives
weakest equating substitution define recursively - Unify(T t, E) Unify(Et/T)?T?t
- (if T?FTV(t))
10Rest of algorithm
- Unify(T t, E) Unify(Et/T)?T?t
- (if T?FTV?t?)
- Unify(?) ?
- Unify(B B, E) Unify(E)
- Unify(B1 B2, E) ?
- Unify(T T, E) Unify(E)
- Unify(t1?t2t3?t4, E)
- Unify(t1t3, t2t4, E)
- Well-founded? Degree (vars, size(eqns))
11Type inference algorithm
- R(e, G, S) ?t, S?? meansReconstructing the
type of e in typing context G with respect to
substitution S yields type t, identical or
stronger substitution S? or - S? is weakest substitution no weaker than than S
such that S?(G) ? e S?(t) - Define Unify(E, S) Unify(SE)?S
- solve substituted equations E and fold in new
substitutions
12Inductive defn of inference
- R(e, G, S) ?t, S?? ? S? is weakest
substitution stronger than (or same as) S such
that S?(G) ? e S?(t) - Unify(E, S) Unify(SE)?S
- R(n, G, S) ?int, S? R(true, G, S) ?bool,
S? - R(x, G, S) ?G(x), S?
- R(e1 e2, G, S) let ?T1, S1? R(e1, G, S) in
- let ?T2, S2? R(e2, G, S1) in
- ?Tf, Unify(T1T2?Tf, S2)?
- R(lx.e, G, S) let ?T1, S1? R(e, Gx?Tf, S) in
- ?Tf ?T1, S1?
- where Tf is fresh (not mentioned anywhere in e,
G, S)
13Example
- R((lx.x) 1, ?, ?)
- let ?T1, S1? R(lx.x, ?, ?) in
- let ?T2, S2? R(1, ?, S1) in
- ?T3, Unify(T1?T3 T2, S2)?
- R(lx.x, ?, ?) let ?T1, S1? R(x, Gx?T4, ?)
in - ?T4?T1, S1?
- ?T4?T4, ??
- let ?T2, S2? R(1, ?, ?) in ?T3, Unify(T2?T3
T4?T4, ?)? - ?T3, Unify(int?T3 T4?T4, ?)?
- ?T3, Unify(intT4, T3 T4, ?)?
- ?T3, Unify(T3 int, T4?int)?
- ?T3, T3 ? int, T4?int)?
14Implementation
- Can implement with imperative update
- datatype type Int Bool Arrow of type
type TypeVar of type option ref - fun freshTypeVar()
- TypeVar(ref NONE)
- fun resolve(t type) case t of
- TypeVar(ref (SOME t)) gt t _ gt t
- fun unify(t1 type, t2 type) unit case
(resolve t1, resolve t2) of (TypeVar(r as ref
NONE), t2) gt r t2 (t1, TypeVar(r as ref
NONE)) gt r t1 (Arrow(t1,t2), Arrow(t3,t4))
gt unify(t1,t3) unify(t2,t4) (Int, Int) gt ()
(Bool,Bool) gt () _ gt raise Fail Cant
unify types
15Polymorphism
- R(lx.x, ?, ?) let ?T1, S1? R(x, Gx?T4, ?) in
- ?T4?T1, S1?
- ?T4?T4, ??
- Reconstruction algorithm doesnt solve type
fully opportunity! - lx.x can have type T4?T4 for any T4
- polymorphic ( many shape) term
- Could reuse same expression multiple places in
program, with different types - let id (lx.x) in (f id) (g x id) id