Implicitly Typed MinHS Inference Algorithm Unification Damas-Milner Type Inference Christine Rizkallah CSE, UNSW Term 3 2020 1
Implicitly Typed MinHS Inference Algorithm Unification Implicitly Typed MinHS Explicitly typed languages are awkward to use 1 . Ideally, we’d like the compiler to determine the types for us. Example What is the type of this function? recfun f x = fst x + 1 We want the compiler to infer the most general type. 1 See Java 2
Implicitly Typed MinHS Inference Algorithm Unification Implicitly Typed MinHS Start with our polymorphic MinHS, then: remove type signatures from recfun , let , etc. remove explicit type abstractions, and type applications (the @ operator). keep ∀ -quantified types. 3
Implicitly Typed MinHS Inference Algorithm Unification Implicitly Typed MinHS Start with our polymorphic MinHS, then: remove type signatures from recfun , let , etc. remove explicit type abstractions, and type applications (the @ operator). keep ∀ -quantified types. remove recursive types, as we can’t infer types for them. see whiteboard for why. 4
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules x : τ ∈ Γ Γ ⊢ x : τ Var 5
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules x : τ ∈ Γ Γ ⊢ x : τ Var Γ ⊢ e 1 : τ 1 → τ 2 Γ ⊢ e 2 : τ 1 App Γ ⊢ e 1 e 2 : τ 2 6
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules x : τ ∈ Γ Γ ⊢ x : τ Var Γ ⊢ e 1 : τ 1 → τ 2 Γ ⊢ e 2 : τ 1 App Γ ⊢ e 1 e 2 : τ 2 Γ ⊢ e 1 : τ 1 Γ ⊢ e 2 : τ 2 Conj I Γ ⊢ ( Pair e 1 e 2 ) : τ 1 × τ 2 7
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules x : τ ∈ Γ Γ ⊢ x : τ Var Γ ⊢ e 1 : τ 1 → τ 2 Γ ⊢ e 2 : τ 1 App Γ ⊢ e 1 e 2 : τ 2 Γ ⊢ e 1 : τ 1 Γ ⊢ e 2 : τ 2 Conj I Γ ⊢ ( Pair e 1 e 2 ) : τ 1 × τ 2 Γ ⊢ e 1 : Bool Γ ⊢ e 2 : τ Γ ⊢ e 3 : τ If Γ ⊢ ( If e 1 e 2 e 3 ) : τ 8
Implicitly Typed MinHS Inference Algorithm Unification Primitive Operators For convenience, we treat prim ops as functions, and place their types in the environment. (+) : Int → Int → Int , Γ ⊢ ( App ( App (+) ( Num 2)) ( Num 1)) : Int 9
Implicitly Typed MinHS Inference Algorithm Unification Functions x : τ 1 , f : τ 1 → τ 2 , Γ ⊢ e : τ 2 Func Γ ⊢ ( Recfun ( f . x . e )) : τ 1 → τ 2 10
Implicitly Typed MinHS Inference Algorithm Unification Sum Types Γ ⊢ e : τ 1 Disj I1 Γ ⊢ InL e : τ 1 + τ 2 Γ ⊢ e : τ 2 Disj I2 Γ ⊢ InR e : τ 1 + τ 2 Note that we allow the other side of the sum to be any type. 11
Implicitly Typed MinHS Inference Algorithm Unification Polymorphism If we have a polymorphic type, we can instantiate it to any type: Γ ⊢ e : ∀ a .τ Γ ⊢ e : τ [ a := ρ ] All E 12
Implicitly Typed MinHS Inference Algorithm Unification Polymorphism If we have a polymorphic type, we can instantiate it to any type: Γ ⊢ e : ∀ a .τ Γ ⊢ e : τ [ a := ρ ] All E We can quantify over any variable that has not already been used. Γ ⊢ e : τ a / ∈ TV (Γ) All I Γ ⊢ e : ∀ a . τ (Where TV (Γ) here is all type variables occurring free in the types of variables in Γ) 13
Implicitly Typed MinHS Inference Algorithm Unification The Goal We want an algorithm for type inference: With a clear input and output. Which terminates. Which is fully deterministic. 14
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules Γ ⊢ e 1 : τ 1 Γ ⊢ e 2 : τ 2 Γ ⊢ ( Pair e 1 e 2 ) : τ 1 × τ 2 Can we use the existing typing rules as our algorithm? infer :: Context → Expr → Type 15
Implicitly Typed MinHS Inference Algorithm Unification Typing Rules Γ ⊢ e 1 : τ 1 Γ ⊢ e 2 : τ 2 Γ ⊢ ( Pair e 1 e 2 ) : τ 1 × τ 2 Can we use the existing typing rules as our algorithm? infer :: Context → Expr → Type This approach can work for monomorphic types, but not polymorphic ones. Why not? 16
Implicitly Typed MinHS Inference Algorithm Unification First Problem Γ ⊢ e : ∀ a .τ Γ ⊢ e : τ [ a := ρ ] All E The rule to add a ∀ -quantifier can always be applied: . . . Γ ⊢ ( Num 5) : ∀ a . ∀ b . Int All E Γ ⊢ ( Num 5) : ∀ a . Int All E Γ ⊢ ( Num 5) : Int This makes the rules give rise to a non-deterministic algorithm – there are many possible rules for a given input. Furthermore, as it can always be applied, a depth-first search strategy may end up attempting infinite derivations. 17
Implicitly Typed MinHS Inference Algorithm Unification Another Problem Γ ⊢ e : ∀ a .τ Γ ⊢ e : τ [ a := ρ ] All E The above rule can be applied at any time to a polymorphic type, even if it would break later typing derivations: Γ ⊢ fst : ∀ a . ∀ b . ( a × b ) → a · · · Γ ⊢ fst : ( Bool × Bool ) → Bool Γ ⊢ ( Pair 1 True) : ( Int × Bool ) Γ ⊢ ( Apply fst ( Pair 1 True)) : ??? 18
Implicitly Typed MinHS Inference Algorithm Unification Yet Another Problem The rule for recfun mentions τ 2 in both input and output positions. x : τ 1 , f : τ 1 → τ 2 , Γ ⊢ e : τ 2 Func Γ ⊢ ( Recfun ( f . x . e )) : τ 1 → τ 2 In order to infer τ 2 we must provide a context that includes τ 2 — this is circular. Any guess we make for τ 2 could be wrong. 19
Implicitly Typed MinHS Inference Algorithm Unification Solution We allow types to include unknowns , also known as unification variables or schematic variables . These are placeholders for types that we haven’t worked out yet. We shall use α, β etc. for these variables. Example ( Int × α ) → β is the type of a function from tuples where the left side of the tuple is Int , but no other details of the type have been determined yet. As we encounter situations where two types should be equal, we unify the two types to determine what the unknown variables should be. 20
Implicitly Typed MinHS Inference Algorithm Unification Example Γ ⊢ fst : ∀ a . ∀ b . ( a × b ) → a · · · Γ ⊢ fst : ( α × β ) → α Γ ⊢ ( Pair 1 True) : ( Int × Bool ) Γ ⊢ ( Apply fst ( Pair 1 True)) : γ 21
Implicitly Typed MinHS Inference Algorithm Unification Example Γ ⊢ fst : ∀ a . ∀ b . ( a × b ) → a · · · Γ ⊢ fst : ( α × β ) → α Γ ⊢ ( Pair 1 True) : ( Int × Bool ) Γ ⊢ ( Apply fst ( Pair 1 True)) : γ ( α × β ) → α ∼ ( Int × Bool ) → γ 22
Implicitly Typed MinHS Inference Algorithm Unification Example Γ ⊢ fst : ∀ a . ∀ b . ( a × b ) → a · · · Γ ⊢ fst : ( α × β ) → α Γ ⊢ ( Pair 1 True) : ( Int × Bool ) Γ ⊢ ( Apply fst ( Pair 1 True)) : γ ( α × β ) → α ∼ ( Int × Bool ) → γ [ α := Int , β := Bool , γ := Int ] 23
Implicitly Typed MinHS Inference Algorithm Unification Unification We call this substitution a unifier . Definition A substitution S to unification variables is a unifier of two types τ and ρ iff S τ = S ρ . Furthermore, it is the most general unifier , or mgu , of τ and ρ if there is no other unifier S ′ where S τ ⊑ S ′ τ . We write τ U ∼ ρ if U is the mgu of τ and ρ . Example (Whiteboard) α × ( α × α ) ∼ β × γ ( α × α ) × β ∼ β × γ Int + α ∼ α + Bool ( α × α ) × α ∼ α × ( α × α ) 24
Implicitly Typed MinHS Inference Algorithm Unification Back to Type Inference We will decompose the typing judgement to allow for an additional output — a substitution that contains all the unifiers we have found about unknowns so far. Inputs Expression, Context Outputs Type, Substitution We will write this as S Γ ⊢ e : τ , to make clear how the original typing judgement may be reconstructed. 25
Implicitly Typed MinHS Inference Algorithm Unification Application, Elimination U S 1 Γ ⊢ e 1 : τ 1 S 2 S 1 Γ ⊢ e 2 : τ 2 S 2 τ 1 ∼ ( τ 2 → α ) ( α fresh) US 2 S 1 Γ ⊢ ( Apply e 1 e 2 ) : U α ( x : ∀ a 1 . ∀ a 2 . . . . ∀ a n . τ ) ∈ Γ ( α 1 . . . α n fresh) Γ ⊢ x : τ [ a 1 := α 1 , a 2 := α 2 , . . . , a n = α n ] Example (Whiteboard) (fst : ∀ a b . ( a × b ) → a ) ⊢ ( Apply fst ( Pair 1 2)) 26
Implicitly Typed MinHS Inference Algorithm Unification Functions U S (Γ , x : α 1 , f : α 2 ) ⊢ e : τ S α 2 ∼ ( S α 1 → τ ) ( α 1 , α 2 fresh) US Γ ⊢ ( Recfun ( f . x . e )) : U ( S α 1 → τ ) Example (Whiteboard) ( Recfun ( f . x . ( Pair x x ))) ( Recfun ( f . x . ( Apply f x ))) 27
Implicitly Typed MinHS Inference Algorithm Unification Generalisation In our typing rules, we could generalise a type to a polymorphic type by introducing a ∀ at any point in the typing derivation. We want to be able to restrict this to only occur in a syntax-directed way. Consider this example: let f = ( recfun f x = ( x , x )) in (fst ( f 4) , fst ( f True )) Where should generalisation happen? 28
Implicitly Typed MinHS Inference Algorithm Unification Let-generalisation To make type inference tractable, we restrict generalisation to only occur when a binding is added to the context via a let expression. 29
Implicitly Typed MinHS Inference Algorithm Unification Let-generalisation To make type inference tractable, we restrict generalisation to only occur when a binding is added to the context via a let expression. This means that let expressions are now not just sugar for a function application, they actually play a vital role in the language’s syntax, as a place for generalisation to occur. 30
Recommend
More recommend