Polymorphism, Subtyping, and Type Inference in MLsub
Stephen Dolan and Alan Mycroft January 18, 2017
Computer Laboratory University of Cambridge
Polymorphism, Subtyping, and Type Inference in MLsub Stephen Dolan - - PowerPoint PPT Presentation
Polymorphism, Subtyping, and Type Inference in MLsub Stephen Dolan and Alan Mycroft January 18, 2017 Computer Laboratory University of Cambridge The select function select p v d = if ( p v ) then v else d In ML, select has type scheme . (
Polymorphism, Subtyping, and Type Inference in MLsub
Stephen Dolan and Alan Mycroft January 18, 2017
Computer Laboratory University of Cambridge
The select function
select p v d = if (p v) then v else d In ML, select has type scheme ∀α. (α → bool) → α → α → α
2
Data flow in select
select p v d = if (p v) then v else d v argument to p result d
3
Data flow in select
select p v d = if (p v) then v else d v argument to p result d In MLsub, select has this type scheme: ∀α, β. (α → bool) → α → β → (α ⊔ β)
3
The MLsub Type System
Expressions of MLsub
We have functions x λx.e e1 e2 ... and records {ℓ1 = e1, . . . , ℓn = en} e.ℓ ... and booleans true false if e1 then e2 else e3 ... and let ˆ x let ˆ x = e1 in e2
7
Typing rules of MLsub
MLsub is ML + (Sub) Γ ⊢ e : τ1 Γ ⊢ e : τ2 τ1 ≤ τ2
9
Constructing Types
The standard definition of types looks like: τ ::= ⊥ | τ → τ | ⊤ (ignoring records and booleans for now)
11
Constructing Types
The standard definition of types looks like: τ ::= ⊥ | τ → τ | ⊤ (ignoring records and booleans for now) with a subtyping relation like: ⊥ ≤ τ τ ≤ ⊤ τ ′
1 ≤ τ1
τ2 ≤ τ ′
2
τ1 → τ2 ≤ τ ′
1 → τ ′ 2
11
Lattices
These types form a lattice:
12
Lattices
These types form a lattice:
e1 : τ1 e2 : τ2 if rand () then e1 else e2 : τ 1 ⊔ τ 2
12
Bizzarely difficult questions
Is this true, for all α? α → α ≤ ⊥ → ⊤
13
Bizzarely difficult questions
Is this true, for all α? α → α ≤ ⊥ → ⊤ How about this? (⊥ → ⊤) → ⊥ ≤ (α → ⊥) ⊔ α
13
Bizzarely difficult questions
Is this true, for all α? α → α ≤ ⊥ → ⊤ How about this? (⊥ → ⊤) → ⊥ ≤ (α → ⊥) ⊔ α Yes, it turns out, by case analysis on α.
13
Bizzarely difficult questions
Is this true, for all α? α → α ≤ ⊥ → ⊤ How about this? (⊥ → ⊤) → ⊥ ≤ (α → ⊥) ⊔ α Yes, it turns out, by case analysis on α. And only by case analysis.
13
Extensibility
Let’s add a new type of function τ1
14
Extensibility
Let’s add a new type of function τ1
It’s a supertype of τ1 → τ2 “function that may have side effects”
14
Extensibility
Let’s add a new type of function τ1
It’s a supertype of τ1 → τ2 “function that may have side effects” Now we have a counterexample: α = (⊤
14
Extensibility and vacuous reasoning
τr = some record type τf = some function type Is τr ⊓ τf ≤ bool?
15
Extensibility and vacuous reasoning
τr = some record type τf = some function type Is τr ⊓ τf ≤ bool? Yes, vacuously.
15
Extensible type systems
Two techniques give us an extensible system:
gets rid of case analysis
16
Extensible type systems
Two techniques give us an extensible system:
gets rid of case analysis
gets rid of vacuous reasoning
16
Resulting types
We end up with all the standard types
17
Resulting types
We end up with all the standard types ... with the same subtyping order
17
Resulting types
We end up with all the standard types ... with the same subtyping order ... but we identify fewer of the weird types {foo : bool} ⊓ (⊤ → ⊤) ≤ bool
17
Type Inference with Polar Types
Input and output types
τ ⊔ τ ′: produces a value which is a τ or a τ ′ τ ⊓ τ ′: requires a value which is a τ and a τ ′ ⊔ is for outputs, and ⊓ is for inputs.
19
Input and output types
τ ⊔ τ ′: produces a value which is a τ or a τ ′ τ ⊓ τ ′: requires a value which is a τ and a τ ′ ⊔ is for outputs, and ⊓ is for inputs. Divide types into
19
Polar types
τ + ::= bool | τ −
1 → τ + 2 | {ℓ1 : τ + 1 , . . . , ℓn : τ + n } |
α | τ +
1 ⊔ τ + 2 | ⊥ | µα.τ +
τ − ::= bool | τ +
1 → τ − 2 | {ℓ1 : τ − 1 , . . . , ℓn : τ − n } |
α | τ −
1 ⊓ τ − 2 | ⊤ | µα.τ −
20
Cases of unification
In HM inference, unification happens in three situations:
another
21
Cases of unification
In HM inference, unification happens in three situations:
Introduce ⊓
Introduce ⊔
another τ + ≤ τ − constraint
21
Eliminating variables, ML-style
Suppose we have an identity function α → α
22
Eliminating variables, ML-style
Suppose we have an identity function, which uses its argument as a τ α → α | α = τ
22
Eliminating variables, ML-style
Suppose we have an identity function, which uses its argument as a τ α → α | α = τ ≡∀ τ → τ
22
Eliminating variables, ML-style
Suppose we have an identity function, which uses its argument as a τ α → α | α = τ ≡∀ τ → τ The substitution [τ/α] solves the constraint α = τ
22
Eliminating variables, MLsub-style
Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ −
23
Eliminating variables, MLsub-style
Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ − ≡∀ (α ⊓ τ −) → α
23
Eliminating variables, MLsub-style
Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ − ≡∀ (α ⊓ τ −) → α The bisubstitution [α ⊓ τ −/α−] solves α ≤ τ −
23
Decomposing constraints
We only need to decompose constraints of the form τ + ≤ τ −. τ1 ⊔ τ2 ≤ τ3 ≡ τ1 ≤ τ3, τ2 ≤ τ3 τ1 ≤ τ2 ⊓ τ3 ≡ τ1 ≤ τ2, τ1 ≤ τ3 Thanks to the input/output type distinction, the hard cases of τ1 ⊓ τ2 ≤ τ3 and τ1 ≤ τ2 ⊔ τ3 can never come up.
24
Combining solutions
We solve a system of multiple constraints C1, C2 by:
Then ξ ◦ ζ solves the system C1, C2.
25
Summary
MLsub infers types by walking the syntax of the program, but must deal with subtyping constraints rather than just equalities. Thanks to:
we can always handle these constraints, producing a principal type.
26
Future work {-# LANGUAGE ?? #-}
27
Questions? http://www.cl.cam.ac.uk/~sd601/mlsub stephen.dolan@cl.cam.ac.uk
28
Mutable references
References are generally considered “invariant”. Instead, consider ref a two-argument constructor (α, β) ref with operations: make : (α, α) ref get : (⊥, β) ref → β set : (α, ⊤) ref → α → unit
29