Polymorphism, Subtyping, and Type Inference in MLsub Stephen Dolan - - PowerPoint PPT Presentation

polymorphism subtyping and type inference in mlsub
SMART_READER_LITE
LIVE PREVIEW

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 . (


slide-1
SLIDE 1

Polymorphism, Subtyping, and Type Inference in MLsub

Stephen Dolan and Alan Mycroft January 18, 2017

Computer Laboratory University of Cambridge

slide-2
SLIDE 2

The select function

select p v d = if (p v) then v else d In ML, select has type scheme ∀α. (α → bool) → α → α → α

2

slide-3
SLIDE 3

Data flow in select

select p v d = if (p v) then v else d v argument to p result d

3

slide-4
SLIDE 4

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

slide-5
SLIDE 5

The MLsub Type System

slide-6
SLIDE 6

Γ ⊢ e : τ

slide-7
SLIDE 7

Γ ⊢ e : τ

slide-8
SLIDE 8

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

slide-9
SLIDE 9

Γ ⊢ e : τ

slide-10
SLIDE 10

Typing rules of MLsub

MLsub is ML + (Sub) Γ ⊢ e : τ1 Γ ⊢ e : τ2 τ1 ≤ τ2

9

slide-11
SLIDE 11

Γ ⊢ e : τ

slide-12
SLIDE 12

Constructing Types

The standard definition of types looks like: τ ::= ⊥ | τ → τ | ⊤ (ignoring records and booleans for now)

11

slide-13
SLIDE 13

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

slide-14
SLIDE 14

Lattices

These types form a lattice:

  • least upper bounds τ1 ⊔ τ2
  • greatest lower bounds τ1 ⊓ τ2

12

slide-15
SLIDE 15

Lattices

These types form a lattice:

  • least upper bounds τ1 ⊔ τ2
  • greatest lower bounds τ1 ⊓ τ2

e1 : τ1 e2 : τ2 if rand () then e1 else e2 : τ 1 ⊔ τ 2

12

slide-16
SLIDE 16

Bizzarely difficult questions

Is this true, for all α? α → α ≤ ⊥ → ⊤

13

slide-17
SLIDE 17

Bizzarely difficult questions

Is this true, for all α? α → α ≤ ⊥ → ⊤ How about this? (⊥ → ⊤) → ⊥ ≤ (α → ⊥) ⊔ α

13

slide-18
SLIDE 18

Bizzarely difficult questions

Is this true, for all α? α → α ≤ ⊥ → ⊤ How about this? (⊥ → ⊤) → ⊥ ≤ (α → ⊥) ⊔ α Yes, it turns out, by case analysis on α.

13

slide-19
SLIDE 19

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

slide-20
SLIDE 20

Extensibility

Let’s add a new type of function τ1

  • → τ2.

14

slide-21
SLIDE 21

Extensibility

Let’s add a new type of function τ1

  • → τ2.

It’s a supertype of τ1 → τ2 “function that may have side effects”

14

slide-22
SLIDE 22

Extensibility

Let’s add a new type of function τ1

  • → τ2.

It’s a supertype of τ1 → τ2 “function that may have side effects” Now we have a counterexample: α = (⊤

  • → ⊥)
  • → ⊥

14

slide-23
SLIDE 23

Extensibility and vacuous reasoning

τr = some record type τf = some function type Is τr ⊓ τf ≤ bool?

15

slide-24
SLIDE 24

Extensibility and vacuous reasoning

τr = some record type τf = some function type Is τr ⊓ τf ≤ bool? Yes, vacuously.

15

slide-25
SLIDE 25

Extensible type systems

Two techniques give us an extensible system:

  • Add explicit type variables as indeterminates

gets rid of case analysis

16

slide-26
SLIDE 26

Extensible type systems

Two techniques give us an extensible system:

  • Add explicit type variables as indeterminates

gets rid of case analysis

  • Require a distributive lattice

gets rid of vacuous reasoning

16

slide-27
SLIDE 27

Resulting types

We end up with all the standard types

17

slide-28
SLIDE 28

Resulting types

We end up with all the standard types ... with the same subtyping order

17

slide-29
SLIDE 29

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

slide-30
SLIDE 30

Type Inference with Polar Types

slide-31
SLIDE 31

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

slide-32
SLIDE 32

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

  • output types τ +
  • input types τ −

19

slide-33
SLIDE 33

Polar types

τ + ::= bool | τ −

1 → τ + 2 | {ℓ1 : τ + 1 , . . . , ℓn : τ + n } |

α | τ +

1 ⊔ τ + 2 | ⊥ | µα.τ +

τ − ::= bool | τ +

1 → τ − 2 | {ℓ1 : τ − 1 , . . . , ℓn : τ − n } |

α | τ −

1 ⊓ τ − 2 | ⊤ | µα.τ −

20

slide-34
SLIDE 34

Cases of unification

In HM inference, unification happens in three situations:

  • Unifying two input types
  • Unifying two output types
  • Using the output of one expression as input to

another

21

slide-35
SLIDE 35

Cases of unification

In HM inference, unification happens in three situations:

  • Unifying two input types

Introduce ⊓

  • Unifying two output types

Introduce ⊔

  • Using the output of one expression as input to

another τ + ≤ τ − constraint

21

slide-36
SLIDE 36

Eliminating variables, ML-style

Suppose we have an identity function α → α

22

slide-37
SLIDE 37

Eliminating variables, ML-style

Suppose we have an identity function, which uses its argument as a τ α → α | α = τ

22

slide-38
SLIDE 38

Eliminating variables, ML-style

Suppose we have an identity function, which uses its argument as a τ α → α | α = τ ≡∀ τ → τ

22

slide-39
SLIDE 39

Eliminating variables, ML-style

Suppose we have an identity function, which uses its argument as a τ α → α | α = τ ≡∀ τ → τ The substitution [τ/α] solves the constraint α = τ

22

slide-40
SLIDE 40

Eliminating variables, MLsub-style

Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ −

23

slide-41
SLIDE 41

Eliminating variables, MLsub-style

Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ − ≡∀ (α ⊓ τ −) → α

23

slide-42
SLIDE 42

Eliminating variables, MLsub-style

Suppose we have an identity function, which uses its argument as a τ −. α → α | α ≤ τ − ≡∀ (α ⊓ τ −) → α The bisubstitution [α ⊓ τ −/α−] solves α ≤ τ −

23

slide-43
SLIDE 43

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

slide-44
SLIDE 44

Combining solutions

We solve a system of multiple constraints C1, C2 by:

  • Solving C1, giving a bisubstitution ξ
  • Applying that to C2
  • Solving ξC2, giving a bisubstitution ζ

Then ξ ◦ ζ solves the system C1, C2.

25

slide-45
SLIDE 45

Summary

MLsub infers types by walking the syntax of the program, but must deal with subtyping constraints rather than just equalities. Thanks to:

  • algebraically well-behaved types
  • polar types, restricting occurrences of ⊔ and ⊓
  • the biunification algorithm

we can always handle these constraints, producing a principal type.

26

slide-46
SLIDE 46

Future work {-# LANGUAGE ?? #-}

  • RankNTypes?
  • GADTs?
  • TypeFamilies?
  • ...

27

slide-47
SLIDE 47

Questions? http://www.cl.cam.ac.uk/~sd601/mlsub stephen.dolan@cl.cam.ac.uk

28

slide-48
SLIDE 48

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