Last time System F ω K 1 is a kind K 2 is a kind ⇒ -kind K 1 ⇒ K 2 is a kind Γ ⊢ A :: K 1 ⇒ K 2 Γ , α :: K 1 ⊢ A :: K 2 Γ ⊢ B :: K 1 ⇒ -intro ⇒ -elim Γ ⊢ λα :: K 1 . A :: K 1 ⇒ K 2 Γ ⊢ A B :: K 2 (and encoding data types: 1, 2, N , +, lists, nested types and ≡ ) 1/ 48
This time Γ ⊢ M : ? 2/ 48
What is type inference? # fun f g x -> f (g x);; - : (’a -> ’b) -> (’c -> ’a) -> ’c -> ’b = <fun > 3/ 48
What is type inference? # fun f g x -> f (g x);; - : (’a -> ’b) -> (’c -> ’a) -> ’c -> ’b = <fun > Goal succinctness of annotation-free code + safety and expressiveness of System F ω 3/ 48
What is type inference? # fun f g x -> f (g x);; - : (’a -> ’b) -> (’c -> ’a) -> ’c -> ’b = <fun > Goal succinctness of annotation-free code + safety and expressiveness of System F ω Bad news the goal is unachievable 3/ 48
The ML calculus 4/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) let id x = x ∀ α. ( ∀ β.β → β ) → α in id id ∀ α.α → ( ∀ β.β → β ) let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) let id x = x ∀ α. ( ∀ β.β → β ) → α in id id ∀ α.α → ( ∀ β.β → β ) let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α in id id ∀ α.α → ( ∀ β.β → β ) let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ∀ α.α → ( ∀ β.β → β ) let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ∀ α.α → ( ∀ β.β → β ) ✗ let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ∀ α.α → ( ∀ β.β → β ) ✗ let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ✓ ∀ α.α → ( ∀ β.β → β ) ✗ let f id = id id in f (fun x -> x) (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ✓ ∀ α.α → ( ∀ β.β → β ) ✗ let f id = id id in f (fun x -> x) ✗ (fun id -> id id) (fun x -> x) 5/ 48
Prenex quantifification Let-bound polymorphism ∀ α.α → α ✓ let id = fun x -> x in id id ∀ α. ∀ β.α → ( β → β ) ✓ ✓ let id x = x ∀ α. ( ∀ β.β → β ) → α ✗ in id id ✓ ∀ α.α → ( ∀ β.β → β ) ✗ let f id = id id in f (fun x -> x) ✗ (fun id -> id id) (fun x -> x) ✗ 5/ 48
Types and schemes B -types Γ ⊢ B is a type Γ ⊢ A is a type Γ ⊢ B is a type α ∈ Γ → -types α -types Γ ⊢ A → B is a type Γ ⊢ α is a type Γ , α ⊢ A is a type scheme Γ ⊢ ∀ α. A is a scheme 6/ 48
Environments Γ- · Γ is an environment · is an environment Γ ⊢ S is a scheme Γ-: Γ, x : S is an environment Γ is an environment Γ-:: Γ , α is an environment 7/ 48
Typing rules for → Γ , x : A ⊢ M : B Γ ⊢ M : A → B → -intro Γ ⊢ N : A Γ ⊢ λ x . M : A → B → -elim Γ ⊢ M N : B 8/ 48
Typing rules for schemes Γ ⊢ M : A α ∩ fv (Γ) = Ø Γ , x : ∀ α. A ⊢ N : B scheme-intro Γ ⊢ let x = M in N : B x : ∀ α. A ∈ Γ Γ ⊢ B is a type (for B ∈ B ) scheme-elim Γ ⊢ x : A [ α := B ] 9/ 48
Milner’s algorithm 10/ 48
Substitutions [ a 1 �→ A 1 , a 2 �→ A 2 , . . . a n �→ A n ] For example, let σ be { a �→ B , b �→ ( B → B ) } A be a → b → a Then σ A is B → ( B → B ) → B . If (for some σ ) σ A = B then we say B is a substitution instance of A . 11/ 48
Constraints a = b a → b = B → b B = B B = B → B 12/ 48
Unification unify : ConstraintSet → Substitution unify( ∅ ) = [] unify( { A = A } ∪ C ) = unify( C ) unify( { a = A } ∪ C ) = unify([ a �→ A ] C ) ◦ [ a �→ A ] when a / ∈ ftv ( A ) unify( { A = a } ∪ C ) = unify([ a �→ A ] C ) ◦ [ a �→ A ] when a / ∈ ftv ( A ) unify( { A → B = A ′ → B ′ } ∪ C ) = unify( { A = A ′ , B = B ′ } ∪ C ) unify( { A = B } ∪ C ) = FAIL 13/ 48
Algorithm J J : Environment × Expression → Type J ( Γ , λ x.M) = b → A J ( Γ , x) = A[ α := b ] where A = J ( Γ ,x: b , M) where Γ (x) = ∀ α. A and b is fresh and b are fresh J ( Γ , M N) = b J ( Γ , let x = M in N) = B where A = J ( Γ , M) where A = J ( Γ , M) and B = J ( Γ , N) and B = J ( Γ ,x: ∀ α. A , N) and unify ’ ({ A = B → b }) and α = ftv( A ) \ ftv( Γ ) succeeds and b is fresh 14/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = 15/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = 16/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = J( · ,f: b 1 , λ x.f x) = 17/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 18/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = 19/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = b 1 20/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = b 1 J( · ,f: b 1 ,x: b 2 , x) = 21/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = b 1 J( · ,f: b 1 ,x: b 2 , x) = b 2 22/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = b 1 J( · ,f: b 1 ,x: b 2 , x) = b 2 unify ({ b 1 = b 2 → b 3 }) = 23/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = b 1 → b 2 → b 3 J( · ,f: b 1 , λ x.f x) = b 2 → b 3 J( · ,f: b 1 ,x: b 2 , f x) = b 3 J( · ,f: b 1 ,x: b 2 , f) = b 1 J( · ,f: b 1 ,x: b 2 , x) = b 2 unify ({ b 1 = b 2 → b 3 }) = { b 1 �→ b 2 → b 3 } 24/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = ( b 2 → b 3 ) → b 2 → b 3 J( · ,f: b 2 → b 3 , λ x.f x) = b 2 → b 3 J( · ,f: b 2 → b 3 ,x: b 2 , f x) = b 3 J( · ,f: b 2 → b 3 ,x: b 2 , f) = b 2 → b 3 J( · ,f: b 2 → b 3 ,x: b 2 , x) = b 2 unify ({ b 1 = b 2 → b 3 }) = { b 1 �→ b 2 → b 3 } 25/ 48
Algorithm J in action J( · , let apply = λ f. λ x.f x in let id = λ y.y in apply id) = J( · , λ f. λ x.f x) = ( b 2 → b 3 ) → b 2 → b 3 J( · ,f: b 2 → b 3 , λ x.f x) = b 2 → b 3 J( · ,f: b 2 → b 3 ,x: b 2 , f x) = b 3 J( · ,f: b 2 → b 3 ,x: b 2 , f) = b 2 → b 3 J( · ,f: b 2 → b 3 ,x: b 2 , x) = b 2 ftv(( b 2 → b 3 ) → b 2 → b 3 ) = { b 2 , b 3 } ftv( · ) = {} { b 2 , b 3 } \ {} = { b 2 , b 3 } 26/ 48
Recommend
More recommend