Transcript
Page 1: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L07-1 September 29, 2011

Type Inference and the Hindley-Milner Type System

Armando Solar-Lezama Computer Science and Artificial Intelligence Laboratory

M.I.T.With slides from Arvind. Used with permission.

September 29, 2011

Page 2: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-2

Type Inference

โ€ข Consider the following expression โ€“ (๐œ†f:int int. f 5) (๐œ†x:int. x + 1)

โ€ข Is it well typed in F1?

Page 3: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-3

Type Inference

โ€ข There wasnโ€™t a single point in the derivation where we had to look at the type labels in order to know what rule to apply! โ€“ we could have written the derivation without the labels

โ€ข The labels helped us determine the actual types for all the ๐œs in the typing rules. โ€“ we could have figured these out even without the labels

โ€“ this is the key idea behind type inference!

Page 4: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-4

Type Inference Strategy 1

โ€ข 1. Use the typing rules to define constraints on the possible types of expressions

โ€ข 2. Solve the resulting constraint system

Page 5: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-5

Deducing Types

1. Assign types to every subexpression x :: t0 f :: t1

f x :: t2 f (f x) :: t3

twice :: ?

twice f x = f (f x)

What is the most "general type" for twice?

2. Set up the constraints t1 = because of (f x) t1 = because of f (f x)

3. Resolve the constraints t0 -> t2 = t2 -> t3

t0 = t2 and t2 = t3 t0 = t2 = t3

twice :: (t0 -> t0) -> t0 -> t0

t1 -> t0 -> t3

t0 -> t2

t2 -> t3

September 8, 2011

Page 6: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-6

The language of Equality Constraints

โ€ข Consider the following Language of Constraints

โ€ข Constraints in this language have a lot of good properties โ€“ Nice and compositional

โ€“ Linear time solution algorithm

Page 7: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-7

Building Constraints from Typing Rules

โ€ข Notation

โ€“ The constraints on the right ensure that the

judgment on the left holds

โ€“ This mapping is defined recursively.

โ€ข Base cases

โ€ข Inductive Cases

ฮ“ โŠข ๐‘’1 + ๐‘’2: ๐œ = ฮ“ โŠข ๐‘’1: ๐‘–๐‘›๐‘ก โˆง ฮ“ โŠข ๐‘’2: ๐‘–๐‘›๐‘ก โˆง ๐œ = ๐‘–๐‘›๐‘ก

Page 8: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-8

Back to our example

o (๐œ†f. f 5) (๐œ†x. x + 1)

Page 9: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-9

Equality and Unification

โ€ข What does it mean for two types a and b to be equal? โ€“ Structural Equality Suppose a = 1 -> 2 b = 3 -> 4 Is a = b ?

iff 1 = 3 and 2 = 4

โ€ข Can two types be made equal by choosing appropriate substitutions for their type variables? โ€“ Robinsonโ€™s unification algorithm Suppose a = t1 -> Bool b = Int -> t2 Are a and b unifiable ? if t1= Int and t2= Bool

Suppose a = t1-> Bool b = Int -> Int

Are a and b unifiable ? No September 27, 2011

Page 10: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-10

Simple Type Substitutions needed to define type unification

A substitution is a map S : Type Variables Types S = [1 / t1,..., n / tn] โ€™ = S โ€™ is a Substitution Instance of Example: S = [(t -> Bool) / t1] S ( t1 -> t1) = ? Substitutions can be composed, i.e., S2 S1

Example:

S1 = [(t -> Bool) / t1] ; S2 = [Int / t]

S2 S1 ( t1 -> t1) ?

Types ::= base types (Int, Bool ..)

| t type variables | -> Function types

( t -> Bool) -> ( t -> Bool)

= S2 (( t -> Bool) -> ( t -> Bool)) = ( Int -> Bool) -> ( Int -> Bool)

September 27, 2011

Page 11: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-11

Unification An essential subroutine for type inference

def Unify(1, 2) = case (1, 2) of

(1, t2) = [1 / t2] provided t2 FV(1) (t1, 2) = [2 / t1] provided t1 FV(2) (1, 2) = if (eq? 1 2) then [ ]

else fail (11->12, 21 ->22) =

Unify(1, 2) tries to unify 1 and 2 and returns a substitution if successful

Does the order matter?

let S1=Unify(11, 21) S2=Unify(S1(12), S1(22)) in S2 S1

otherwise = fail

No

September 27, 2011

Page 12: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-12

Type inference strategy 2

โ€ข Like strategy 1, but we solve the constraints as we see them โ€“ Build the substitution map incrementally

September 29, 2011

Page 13: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-13

Simple Inference Algorithm

W(TE, e) returns (S,) such that S (TE) โ”œ e :

The type environment TE records the most general type of each identifier while the substitution S records the changes in the type variables

Def W(TE, e) = Case e of x = ... n = ... x.e = ... (e1 e2) = ... ...

September 27, 2011

This is just ฮ“ (itโ€™s hard to write ฮ“ in code)

Page 14: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-14

Simple Inference Algorithm (cont-1)

Def W(TE, e) = Case e of

N = x = x.e = (e1 e2) =

let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

September 27, 2011

let (S1, 2)= W(TE + { x : u }, e) in (S1, S1(u) -> 2)

if (x Dom(TE)) then Fail else let = TE(x); in ({}, )

({}, Typeof(N))

uโ€™s represent new type variables

Page 15: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-15

Simple Inference Algorithm (cont-1)

Def W(TE, e) = Case e of

c = x = x.e = (e1 e2) =

let x = e1 in e2 =

uโ€™s represent new type variables

let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

let (S1, 1) = W(TE + {x : u}, e1); S2 = Unify(S1(u), 1); (S3, 2) = W(S2 S1(TE) + {x : }, e2); in (S3 S2 S1, 2)

September 27, 2011

let (S1, 1) = W(TE + { x : u }, e) in (S1, S1(u) -> 1)

if (x Dom(TE)) then Fail else let = TE(x); in ({}, )

({}, Typeof(c))

Page 16: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example Def W(TE, e) =

Case e of

โ€ฆ

x.e = let (S1, 1) = W(TE + { x : u }, e) in (S1, S1(u) -> 1)

(e1 e2) = let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

๐‘Š(โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ )

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 =

๐‘Š ๐‘“: ๐‘ข0 , ๐‘“ 5 =

๐‘Š ๐‘“:๐‘ข0 , ๐‘“ = (โˆ…, ๐‘ข0) ๐‘Š ๐‘“:๐‘ข0 , 5 = (โˆ…, ๐ผ๐‘›๐‘ก)

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐‘ข0, ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 =

Page 17: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example

๐‘Š(โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ )

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 =

๐‘Š ๐‘“: ๐‘ข0 , ๐‘“ 5 =

๐‘Š ๐‘“:๐‘ข0 , ๐‘“ = (โˆ…, ๐‘ข0) ๐‘Š ๐‘“:๐‘ข0 , 5 = (โˆ…, ๐ผ๐‘›๐‘ก)

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐‘ข0, ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 =

def Unify(1, 2) = case (1, 2) of

(1, t2) = [1 / t2] provided t2 FV(1)

(t1, 2) = [2 / t1] provided t1 FV(2)

(1, 2) = if (eq? 1 2) then [ ] else fail

(11->12, 21 ->22) = let S1=Unify(11, 21) S2=Unify(S1(12), S1(22))

in S2 S1

[(๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 ]

Page 18: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example

๐‘Š(โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ )

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 =

๐‘Š ๐‘“: ๐‘ข0 , ๐‘“ 5 =

๐‘Š ๐‘“:๐‘ข0 , ๐‘“ = (โˆ…, ๐‘ข0) ๐‘Š ๐‘“:๐‘ข0 , 5 = (โˆ…, ๐ผ๐‘›๐‘ก)

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐‘ข0, ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 = [(๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 ]

Def W(TE, e) =

Case e of

โ€ฆ

x.e = let (S1, 1) = W(TE + { x : u }, e) in (S1, S1(u) -> 1)

(e1 e2) = let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

([๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 ๐‘ข0 ], ๐‘ข1)

( (๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 , ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1)

Page 19: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example

๐‘Š(โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ )

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 =

Def W(TE, e) =

Case e of

โ€ฆ

x.e = let (S1, 1) = W(TE + { x : u }, e) in (S1, S1(u) -> 1)

(e1 e2) = let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

( (๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 , ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1)

๐‘Š โˆ…, ๐œ†๐‘ฅ. ๐‘ฅ = (โˆ…, ๐‘ข3 โ†’ ๐‘ข3)

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1, ๐‘ข3 โ†’ ๐‘ข3 โ†’ ๐‘ข4 =

Page 20: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example

๐‘Š(โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ )

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1, ๐‘ข3 โ†’ ๐‘ข3 โ†’ ๐‘ข4 =

def Unify(1, 2) = case (1, 2) of

(1, t2) = [1 / t2] provided t2 FV(1)

(t1, 2) = [2 / t1] provided t1 FV(2)

(1, 2) = if (eq? 1 2) then [ ] else fail

(11->12, 21 ->22) = let S1=Unify(11, 21) S2=Unify(S1(12), S1(22))

in S2 S1

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐ผ๐‘›๐‘ก, ๐‘ข4 = [๐ผ๐‘›๐‘ก ๐‘ข4 ]

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 , ๐‘ข3 โ†’ ๐‘ข3 = ๐ผ๐‘›๐‘ก ๐‘ข3 ; ๐ผ๐‘›๐‘ก ๐‘ข1

๐ผ๐‘›๐‘ก ๐‘ข3 ; ๐ผ๐‘›๐‘ก ๐‘ข1 ; ๐ผ๐‘›๐‘ก/๐‘ข4

Page 21: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

Example

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 ๐œ†๐‘ฅ. ๐‘ฅ =

๐‘Š โˆ…, ๐œ†๐‘“. ๐‘“ 5 =

Def W(TE, e) =

Case e of

โ€ฆ

x.e = let (S1, 1) = W(TE + { x : u }, e) in (S1, S1(u) -> 1)

(e1 e2) = let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

( (๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 , ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1)

๐‘Š โˆ…, ๐œ†๐‘ฅ. ๐‘ฅ = (โˆ…, ๐‘ข3 โ†’ ๐‘ข3)

๐‘ˆ๐‘›๐‘–๐‘“๐‘ฆ ๐ผ๐‘›๐‘ก โ†’ ๐‘ข1 โ†’ ๐‘ข1, ๐‘ข3 โ†’ ๐‘ข3 โ†’ ๐‘ข4 = ๐ผ๐‘›๐‘ก ๐‘ข3 ; ๐ผ๐‘›๐‘ก ๐‘ข1 ; ๐ผ๐‘›๐‘ก/๐‘ข4

( (๐ผ๐‘›๐‘ก โ†’ ๐‘ข1) ๐‘ข0 ; ๐ผ๐‘›๐‘ก ๐‘ข3 ; ๐ผ๐‘›๐‘ก ๐‘ข1 ; ๐ผ๐‘›๐‘ก/๐‘ข4 , ๐ผ๐‘›๐‘ก)

Page 22: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-22

What about Let?

โ€ข ๐‘™๐‘’๐‘ก ๐‘ฅ = ๐‘’1 ๐‘–๐‘› ๐‘’2

โ€ข Typing rule

โ€“ฮ“;๐‘ฅ:๐œโ€ฒโŠข๐‘’1:๐œ

โ€ฒ ฮ“;๐‘ฅ:๐œโ€ฒโŠข๐‘’2:๐œ

ฮ“ โŠข๐‘™๐‘’๐‘ก ๐‘ฅ=๐‘’1๐‘–๐‘› ๐‘’2โˆถ๐œ

โ€ข Constraints โ€“ ฮ“ โŠข ๐‘™๐‘’๐‘ก ๐‘ฅ = ๐‘’1๐‘–๐‘› ๐‘’2 โˆถ ๐œ =

โˆƒ๐œโ€ฒ, ฮ“; ๐‘ฅ: ๐œโ€ฒ โŠข ๐‘’1: ๐œโ€ฒ โˆง ฮ“; ๐‘ฅ: ๐œโ€ฒ โŠข ๐‘’2: ๐œ

โ€ข Algorithm

September 29, 2011

Case Exp = let x = e1 in e2 => let (S1, 1) = W(TE + {x : u}, e1); S2 = Unify(S1(u), 1); (S3, 2) = W(S2 S1(TE) + {x : }, e2); in (S3 S2 S1, 2)

This is Hindley Milner

without polymorphism

Page 23: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-23

Polymorphism

September 27, 2011

Page 24: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-24

Some observations

โ€ข A type system restricts the class of programs that are considered โ€œlegalโ€

โ€ข It is possible a term in the untyped โ€“calculus may be reducible to a value but may not be typeable in a particular type system

let id = x. x in

... (id True) ... (id 1) ...

This term is not typeable in the simple type system we have discussed so far. However, it is typeable in the Hindley-Milner system

September 29, 2011

Page 25: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-25

Explicit polymorphism

โ€ข Youโ€™ve seen this before

โ€ข How do we formalize this?

โ€ข Example

๐‘–๐‘‘ = ฮ›๐‘‡. ๐œ†๐‘ฅ โˆถ ๐‘‡. ๐‘ฅ

๐‘–๐‘‘ ๐‘–๐‘›๐‘ก 5 September 27, 2011

public interface List<E>{

void add(E x);

E get();

}

List<String> ls = ...

ls.add("Hello");

String hello = ls.get(0);

ฮ“ โŠข ๐‘’ โˆถ ๐œ

ฮ“ โŠข ฮ›๐‘ก. ๐‘’ โˆถ โˆ€๐‘ก. ๐œ

ฮ“ โŠข ๐‘’ โˆถ โˆ€๐‘ก. ๐œโ€ฒ

ฮ“ โŠข ๐‘’[๐œ] โˆถ ๐œโ€ฒ[๐œ / ๐‘ก]

Page 26: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-26

Different Styles of Polymorphism

โ€ข Impredicative Polymorphism

๐œ ::= ๐‘ ๐œ1 โ†’ ๐œ2 ๐‘‡ | โˆ€๐‘‡. ๐œ

e ::= ๐‘ฅ ๐œ†๐‘ฅ: ๐œ. ๐‘’ ๐‘’1๐‘’2 ฮ›T. e e[๐œ]

โ€ข Very powerful โ€“ Although you still canโ€™t express recursion

โ€ข Type inference is undecidable !

Page 27: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-27

Different Styles of Polymorphism

โ€ข Predicative Polymorphism

๐œ ::= ๐‘ ๐œ1 โ†’ ๐œ2 ๐‘‡

๐œŽ โˆท= ๐œ โˆ€๐‘‡. ๐œŽ ๐œŽ1 โ†’ ๐œŽ2

e ::= ๐‘ฅ ๐œ†๐‘ฅ: ๐œŽ. ๐‘’ ๐‘’1๐‘’2 ฮ›T. e e[๐œ]

โ€ข Still very powerful โ€“ But you can no longer instantiate with a polymorphic type

โ€ข Type inference is still undecidable !

Page 28: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-28

Different Styles of Polymorphism

โ€ข Prenex Predicative Polymorphism

๐œ ::= ๐‘ ๐œ1 โ†’ ๐œ2 ๐‘‡

๐œŽ โˆท= ๐œ |โˆ€๐‘‡. ๐œŽ

e ::= ๐‘ฅ ๐œ†๐‘ฅ: ๐œ. ๐‘’ ๐‘’1๐‘’2 ฮ›T. e e[๐œ]

โ€ข Now we have decidable type inference

โ€ข But polymorphism is now very limited โ€“ We canโ€™t pass polymorphic functions as arguments!!

โ€“ (๐œ†๐‘ : โˆ€๐‘‡ . ๐œ โ€ฆ ๐‘  ๐‘–๐‘›๐‘ก ๐‘ฅ โ€ฆ ๐‘  ๐‘๐‘œ๐‘œ๐‘™ ๐‘ฅ)(ฮ›๐‘‡. ๐‘๐‘œ๐‘‘๐‘’ ๐‘“๐‘œ๐‘Ÿ ๐‘ ๐‘œ๐‘Ÿ๐‘ก)

Page 29: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-29

Let polymorphism

โ€ข Introduce let x = e1 in e2 โ€“ Just like saying ๐œ†๐‘ฅ. ๐‘’2 ๐‘’1

โ€“ Except x can be polymorphic

โ€ข Good engineering compromise โ€“ Enhance expressiveness

โ€“ Preserve decidability

โ€ข This is the Hindley Milner type system

September 29, 2011

Page 30: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-30

Type inference with polymorphism

September 27, 2011

Page 31: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-31

Polymorphic Types

Constraints:

let id = x. x in

... (id True) ... (id 1) ...

id :: t1 --> t1 id :: Int --> t2 id :: Bool --> t3

Does not unify!!

id :: t1. t1 --> t1

Different uses of a generalized type variable may be instantiated differently

id2 : Bool --> Bool id1 : Int --> Int

Solution: Generalize the type variable

When can we

generalize?

September 29, 2011

Page 32: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-32

A mini Language to study Hindley-Milner Types

โ€ข There are no types in the syntax of the language! โ€ข The type of each subexpression is derived by the

Hindley-Milner type inference algorithm.

Expressions E ::= c constant

| x variable | x. E abstraction | (E1 E2) application | let x = E1 in E2 let-block

September 29, 2011

Page 33: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-33

A Formal Type System

Note, all the โ€™s occur in the beginning of a type scheme, i.e., a type cannot contain a type scheme

Types ::= base types

| t type variables | 1 -> 2 Function types

Type Schemes ::= | t.

Type Environments TE ::= Identifiers Type Schemes

September 29, 2011

Page 34: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-34

Instantiations

โ€ข Type scheme can be instantiated into a type โ€™ by substituting types for the bound variables of , i.e., โ€™ = S for some S s.t. Dom(S) BV()

- โ€™ is said to be an instance of ( > โ€™)

- โ€™ is said to be a generic instance of when S

maps variables to new variables.

= t1...tn.

Example: =t1. t1 -> t2

t3 -> t2 is a generic instance of Int -> t2 is a non generic instance of

September 29, 2011

Page 35: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-35

Generalization aka Closing

โ€ข Generalization introduces polymorphism

โ€ข Quantify type variables that are free in but not free in the type environment (TE)

โ€ข Captures the notion of new type variables of

Gen(TE,) = t1...tn. where { t1...tn } = FV() - FV(TE)

September 29, 2011

Page 36: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-36

HM Type Inference Rules

(App) ฮ“โŠข๐‘’1:๐œโ†’๐œโ€ฒ ฮ“โŠข๐‘’2:๐œ

ฮ“โŠข ๐‘’1๐‘’2 :๐œโ€ฒ

(Abs) ฮ“ ; ๐‘ฅ:๐œ โŠข๐‘’โˆถ๐œโ€ฒ

ฮ“โŠข๐œ†๐‘ฅ.๐‘’โˆถ๐œโ†’๐œโ€ฒ

(Var) ๐‘ฅ:๐œŽ โˆˆฮ“ ๐œŽโ‰ฅ๐œ

ฮ“โŠข๐‘ฅ:๐œ

(Const) ๐‘ก๐‘ฆ๐‘๐‘’๐‘œ๐‘“(๐‘)โ‰ฅ๐œ

ฮ“โŠข๐‘:๐œ

(Let) ฮ“; ๐‘ฅ:๐œ โŠข๐‘’1:๐œ ฮ“; ๐‘ฅ:๐บ๐‘’๐‘›(ฮ“,๐œ) โŠข๐‘’2:๐œโ€ฒ

ฮ“โŠข(๐‘™๐‘’๐‘ก ๐‘ฅ=๐‘’1 ๐‘–๐‘› ๐‘’2):๐œโ€ฒ

September 29, 2011

๐‘ฅ can be considered of type ๐œ as long as its type as specified in the environment can be specialized to ๐œ (i.e. ๐œ is an instance of ๐œŽ)

Note: x has a different type in ๐‘’1 than in ๐‘’2. In ๐‘’1, x is not a polymorphic type, but in ๐‘’2 it gets generalized into one.

Remember, ๐œ stands for a monotype, ๐œŽ for a polymorphic type

Page 37: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-37

HM Inference Algorithm

Def W(TE, e) = Case e of c = ({}, Typeof(c)) x = x.e = (e1 e2) =

let x = e1 in e2 =

uโ€™s represent new type variables

let (S1, 1) = W(TE, e1); (S2, 2) = W(S1(TE), e2); S3 = Unify(S2(1), 2 -> u); in (S3 S2 S1, S3(u))

if (x Dom(TE)) then Fail else let t1...tn. = TE(x); in ( { }, [ui / ti] )

let (S1, 1) = W(TE + { x : u }, e); in (S1, S1(u) -> 1)

let (S1, 1) = W(TE + {x : u}, e1); S2 = Unify(S1(u), 1); = Gen(S2 S1(TE), S2(1) ); (S3, 2) = W(S2 S1(TE) + {x : }, e2); in (S3 S2 S1, 2)

September 29, 2011

Page 38: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-38

Hindley-Milner: Example

x. let f = y.x

in (f 1, f True)

W(, A) =

W({x : u1}, B) =

( [ ] , u1 )

( [ ] , u3 -> u1 )

u3.u3 -> u1

TE = {x : u1, f : u3.u3 -> u1}

( [ ] , u4 -> u1 )

W(TE, 1) = ( [ ] , Int ) [ Int / u4 , u1 / u5 ]

( [ ] , u1 )

( [ ] , (u1,u1) )

Unify(u4 -> u1 , Int -> u5) =

W({x : u1, f : u2, y : u3}, x) =

W({x : u1, f : u2}, y.x) =

Gen({x : u1}, u3 -> u1) =

W(TE, (f 1) ) =

( [ ] , u1 -> (u1,u1) )

W(TE, f) =

Unify(u2 , u3 -> u1) =

A B

[ (u3 -> u1) / u2 ]

... September 29, 2011

Page 39: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-39

Important Observations

โ€ข Do not generalize over type variables used elsewhere

โ€ข Let is the only way of defining polymorphic constructs

โ€ข Generalize the types of let-bound identifiers only after processing their definitions

September 29, 2011

Page 40: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-40

Properties of HM Type Inference

โ€ข It is sound with respect to the type system. An inferred type is verifiable.

โ€ข It generates most general types of expressions. Any verifiable type is inferred.

โ€ข Complexity

PSPACE-Hard Nested let blocks

September 29, 2011

Page 41: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-41

Extensions

โ€ข Type Declarations Sanity check; can relax restrictions

โ€ข Incremental Type checking The whole program is not given at the same time, sound inferencing when types of some functions are not known

โ€ข Typing references to mutable objects Hindley-Milner system is unsound for a language with refs (mutable locations) โ€ข Overloading Resolution

September 29, 2011

Page 42: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-42

HM Limitations: -bound vs Let-bound Variables

Only let-bound identifiers can be instantiated differently.

let twice f x = f (f x) in twice twice succ 4

versus let twice f x = f (f x) foo g = (g g succ) 4 in foo twice

foo is not type correct !

Generic vs. Non-generic type variables

September 29, 2011

Page 43: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

L06-43

Puzzle: Another set of Inference rules

(Gen) TE โ”œ e : t FV(TE)

TE โ”œ e : t. (Spec) TE โ”œ e : t.

TE โ”œ e : [u/t]

(Var) (x : ) TE

TE โ”œ x :

(Let) TE+{x:} โ”œ e1: TE+{x:} โ”œ e2:โ€™

TE โ”œ (let x = e1 in e2) : โ€™

(App) and (Abs) rules remain unchanged.

Sound but no inference algorithm !

September 29, 2011

Page 44: Type Inference and the Hindley-Milner Type Systemย ยท โ€ขIntroduce let x = e1 in e2 โ€“ Just like saying ๐œ† . 2 1 โ€“ Except x can be polymorphic โ€ขGood engineering compromise โ€“

MIT OpenCourseWare

http://ocw.mit.edu

6.820 Fundamentals of Program AnalysisFall 2015

For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.


Top Related