Last time: phantom types type a t = int 1/ 49 This time: GADTs a - - PowerPoint PPT Presentation

last time phantom types
SMART_READER_LITE
LIVE PREVIEW

Last time: phantom types type a t = int 1/ 49 This time: GADTs a - - PowerPoint PPT Presentation

Last time: phantom types type a t = int 1/ 49 This time: GADTs a b 2/ 49 What we gain : : (Addtionally, some programs become faster!) 3/ 49 What we gain : : (Addtionally, some programs


slide-1
SLIDE 1

Last time: phantom types

type ’a t = int

1/ 49

slide-2
SLIDE 2

This time: GADTs

a ≡ b

2/ 49

slide-3
SLIDE 3

What we gain

⇓ Γ ⊢: Γ ⊢: ⇓ (Addtionally, some programs become faster!)

3/ 49

slide-4
SLIDE 4

What we gain

⇓ Γ ⊢: Γ ⊢: ⇓ (Addtionally, some programs become faster!)

3/ 49

slide-5
SLIDE 5

What it costs

We’ll need to: describe our data more precisely strengthen the relationship between data and types look at programs through a propositions-as-types lens

4/ 49

slide-6
SLIDE 6

What we’ll write

Non-regularity in constructor return types type t = T : t1 → t2 t Locally abstract types: l e t f : type a b. a t → b t = f u n c t i o n . . . l e t g (type a) (type b) ( x : a t ) : b t = . . .

5/ 49

slide-7
SLIDE 7

Nested types review

6/ 49

slide-8
SLIDE 8

Unconstrained trees

T T T E a E b E c E type ’ a t r e e = Empty : ’ a t r e e | Tree : ’ a t r e e ∗ ’ a ∗ ’ a t r e e → ’ a t r e e

7/ 49

slide-9
SLIDE 9

Functions on unconstrained trees

v a l ? : ’ a t r e e → i n t v a l ? : ’ a t r e e → ’ a option v a l ? : ’ a t r e e → ’ a t r e e

8/ 49

slide-10
SLIDE 10

Unconstrained trees: depth

T T T E a E b E c E

1 + max (1 + max (1 + max 0) 0) l e t rec depth : ’ a . ’ a t r e e → i n t = f u n c t i o n Empty → 0 | Tree ( l , , r ) → 1 + max ( depth l ) ( depth r )

9/ 49

slide-11
SLIDE 11

Unconstrained trees: top

T T T E a E b E c E

Some c l e t top : ’ a . ’ a t r e e → ’ a option = f u n c t i o n Empty → None | Tree ( , v , ) → Some v

10/ 49

slide-12
SLIDE 12

Unconstrained trees: swivel

T T T E a E b E c E T E c T E b T E a E

l e t rec s w i v e l : ’ a . ’ a t r e e → ’ a t r e e = f u n c t i o n Empty → Empty | Tree ( l , v , r ) → Tree ( s w i v e l r , v , s w i v e l l )

11/ 49

slide-13
SLIDE 13

Perfect leaf trees via nesting

S S S Z a b c d e f g h type ’ a p e r f e c t = ZeroP : ’ a → ’ a p e r f e c t | SuccP : ( ’ a ∗ ’ a ) p e r f e c t → ’ a p e r f e c t

12/ 49

slide-14
SLIDE 14

Perfect (branch) trees via nesting

T a T (b, c) T ((d, e), (f, g)) E type ntree = EmptyN : ’ a ntree | TreeN : ’ a ∗ ( ’ a ∗ ’ a ) ntree → ’ a ntree

13/ 49

slide-15
SLIDE 15

Functions on perfect nested trees

v a l ? : ’ a ntree → i n t v a l ? : ’ a ntree → ’ a option v a l ? : ’ a ntree → ’ a ntree

14/ 49

slide-16
SLIDE 16

Perfect trees: depth

T a T (b, c) T ((d, e), (f, g)) E

1 + 1 + 1 + l e t rec depthN : ’ a . ’ a ntree → i n t = f u n c t i o n EmptyN → 0 | TreeN ( , t ) → 1 + depthN t

15/ 49

slide-17
SLIDE 17

Perfect trees: top

T a T (b, c) T ((d, e), (f, g)) E

Some a l e t rec topN : ’ a . ’ a ntree → ’ a option = f u n c t i o n EmptyN → None | TreeN ( v , ) → Some v

16/ 49

slide-18
SLIDE 18

Perfect trees: swivel

T a T (b, c) T ((d, e), (f, g)) E T a T (c, b) T ((g, f), (e, d)) E

l e t rec swiv : ’ a . ( ’ a→ ’ a ) → ’ a ntree → ’ a ntree = fun f t → match t with EmptyN → EmptyN | TreeN ( v , t ) → TreeN ( f v , swiv ( fun ( x , y ) → ( f y , f x )) t ) l e t swivelN p = swiv id p

17/ 49

slide-19
SLIDE 19

GADTs

18/ 49

slide-20
SLIDE 20

Perfect trees, take two

T[3] T[2] T[1] E d E b T[1] E e E a T[2] T[1] E f E c T[1] E g E

type ( ’ a , ) g t r e e = EmptyG : ( ’ a , z ) g t r e e | TreeG : ( ’ a , ’ n) g t r e e ∗ ’ a ∗ ( ’ a , ’ n) g t r e e → ( ’ a , ’ n s ) g t r e e

19/ 49

slide-21
SLIDE 21

Natural numbers

type z = Z type s = S : ’n → ’n s # l e t zero = Z ; ; v a l zero : z = Z # l e t three = S (S (S Z ) ) ; ; v a l three : z s s s = S (S (S Z))

20/ 49

slide-22
SLIDE 22

Functions on perfect trees (GADTs)

v a l ? : ( ’ a , ’ n) g t r e e → ’n v a l ? : ( ’ a , ’ n s ) g t r e e → ’ a v a l ? : ( ’ a , ’ n) g t r e e → ( ’ a , ’ n) g t r e e

21/ 49

slide-23
SLIDE 23

Perfect trees (GADTs): depth

T[2] T[1] E d E b T[1] E e E

S ( depth S ( depth Z)) l e t rec depthG : type a n . ( a , n) g t r e e → n = f u n c t i o n EmptyG → Z | TreeG ( l , , ) → S ( depthG l )

22/ 49

slide-24
SLIDE 24

Perfect trees (GADTs): depth

type ( ’ a , ) g t r e e = EmptyG : ( ’ a , z ) g t r e e | TreeG : ( ’ a , ’ n) g t r e e ∗ ’ a ∗ ( ’ a , ’ n) g t r e e → ( ’ a , ’ n s ) g t r e e l e t rec depthG : type a n . ( a , n) g t r e e → n = f u n c t i o n EmptyG → Z | TreeG ( l , , ) → S ( depthG l )

Type refinement In the EmptyG branch: n ≡ z In the TreeG branch: n ≡ m s (for some m) l : (a, m) gtree depthG l : m Polymorphic recursion The argument to the recursive call has size m (s.t. s m ≡ n)

23/ 49

slide-25
SLIDE 25

Perfect trees (GADTs): top

T[2] T[1] E b E a T[1] E c E

a l e t topG : type a n . ( a , n s ) g t r e e → a = f u n c t i o n TreeG ( , v , ) → v

24/ 49

slide-26
SLIDE 26

Perfect trees (GADTs): depth

type ( ’ a , ) g t r e e = EmptyG : ( ’ a , z ) g t r e e | TreeG : ( ’ a , ’ n) g t r e e ∗ ’ a ∗ ( ’ a , ’ n) g t r e e → ( ’ a , ’ n s ) g t r e e l e t topG : type a n . ( a , n s ) g t r e e → a = f u n c t i o n TreeG ( , v , ) → v

Type refinement In an EmptyG branch we would have: n s ≡ z — impossible!

25/ 49

slide-27
SLIDE 27

Perfect trees (GADTs): swivel

T[2] T[1] E b E a T[1] E c E T[2] T[1] E c E a T[1] E b E

l e t rec swivelG : type a n . ( a , n) g t r e e → (a , n) g t r e e = f u n c t i o n EmptyG → EmptyG | TreeG ( l , v , r ) → TreeG ( swivelG r , v , swivelG l )

26/ 49

slide-28
SLIDE 28

Perfect trees (GADTs): swivel

type ( ’ a , ) g t r e e = EmptyG : ( ’ a , z ) g t r e e | TreeG : ( ’ a , ’ n) g t r e e ∗ ’ a ∗ ( ’ a , ’ n) g t r e e → ( ’ a , ’ n s ) g t r e e l e t rec swivelG : type a n . ( a , n) g t r e e → (a , n) g t r e e = f u n c t i o n EmptyG → EmptyG | TreeG ( l , v , r ) → TreeG ( swivelG r , v , swivelG l )

Type refinement In the EmptyG branch: n ≡ z In the TreeG branch: n ≡ m s (for some m) l , r : (a, m) gtree swivelG l : (a, m) gtree Polymorphic recursion The argument to the recursive call has size m (s.t. s m ≡ n)

27/ 49

slide-29
SLIDE 29

Zipping perfect trees

T[2] T[1] E b E a T[1] E c E T[2] T[1] E e E d T[1] E f E T[2] T[1] E (b,e) E (a,d) T[1] E (c,f) E l e t rec zipTree : type a n . ( a , n) g t r e e → (a , n) g t r e e → ( a ∗ a , n) g t r e e = fun x y → match x , y with EmptyG , EmptyG → EmptyG | TreeG ( l , v , r ) , TreeG (m,w, s ) → TreeG ( zipTree l m, ( v ,w) , zipTree r s )

28/ 49

slide-30
SLIDE 30

Zipping perfect trees

type ( ’ a , ) g t r e e = EmptyG : ( ’ a , z ) g t r e e | TreeG : ( ’ a , ’ n) g t r e e ∗ ’ a ∗ ( ’ a , ’ n) g t r e e → ( ’ a , ’ n s ) g t r e e l e t rec zipTree : type a n . ( a , n) g t r e e → (a , n) g t r e e → ( a ∗ a , n) g t r e e = fun x y → match x , y with EmptyG , EmptyG → EmptyG | TreeG ( l , v , r ) , TreeG (m,w, s ) → TreeG ( zipTree l m, ( v ,w) , zipTree r s )

Type refinement In the EmptyG branch: n ≡ z In the TreeG branch: n ≡ m s (for some m) EmptyG, TreeG produces n ≡ z and n ≡ m s — impossible!

29/ 49

slide-31
SLIDE 31

Conversions between perfect tree representations

T[2] T[1] E b E a T[1] E c E T a T (b, c) E

l e t rec n e s t i f y : type a n . ( a , n) g t r e e → a ntree = f u n c t i o n EmptyG → EmptyN | TreeG ( l , v , r ) → TreeN ( v , n e s t i f y ( zipTree l r ))

30/ 49

slide-32
SLIDE 32

Depth-annotated trees

T[2] max(1,0)≡1 T[1] max(0,0)≡0 E a E b E

type ( ’ a , ) d t r e e = EmptyD : ( ’ a , z ) d t r e e | TreeD : ( ’ a , ’m) d t r e e ∗ ’ a ∗ ( ’ a , ’ n ) d t r e e ∗ ( ’m, ’ n , ’ o ) max → ( ’ a , ’ o s ) d t r e e

31/ 49

slide-33
SLIDE 33

The untyped maximum function

val max : ’a → ’a → ’a Parametricity: max is one of fun x → x fun y → y

32/ 49

slide-34
SLIDE 34

A typed maximum function

val max : (’a ,’ b,’c) max → ’a → ’b → ’c (max (a,b) ≡ c) → a → b → c

33/ 49

slide-35
SLIDE 35

A typed maximum function: equality

type ( , ) e q l = R e f l : ( ’ a , ’ a ) e q l a ≡ a

34/ 49

slide-36
SLIDE 36

A typed maximum function: a max predicate

type ( , ) e q l = R e f l : ( ’ a , ’ a ) e q l type ( , , ) max = MaxEq : ( ’ a , ’ b) e q l → ( ’ a , ’ b , ’ a ) max | MaxFlip : ( ’ a , ’ b , ’ c ) max → ( ’ b , ’ a , ’ c ) max | MaxSuc : ( ’ a , ’ b , ’ a ) max → ( ’ a s , ’ b , ’ a s ) max a ≡ b → max(a,b) ≡ a max(a,b) ≡ c → max(b,a) ≡ c max(a,b) ≡ a → max(a+1,b) ≡ a+1

35/ 49

slide-37
SLIDE 37

A typed maximum function

type ( , ) e q l = R e f l : ( ’ a , ’ a ) e q l type ( , , ) max = MaxEq : ( ’ a , ’ b) e q l → ( ’ a , ’ b , ’ a ) max | MaxFlip : ( ’ a , ’ b , ’ c ) max → ( ’ b , ’ a , ’ c ) max | MaxSuc : ( ’ a , ’ b , ’ a ) max → ( ’ a s , ’ b , ’ a s ) max l e t rec max : type a b c . ( a , b , c ) max → a → b → c = fun mx m n → match mx,m with MaxEq R e f l , → m | MaxFlip mx’ , → max mx’ n m | MaxSuc mx’ , S m’ → S (max mx’ m’ n)

36/ 49

slide-38
SLIDE 38

A typed maximum function

type ( , , ) max = MaxEq : ( ’ a , ’ b) e q l → ( ’ a , ’ b , ’ a ) max | MaxFlip : ( ’ a , ’ b , ’ c ) max → ( ’ b , ’ a , ’ c ) max | MaxSuc : ( ’ a , ’ b , ’ a ) max → ( ’ a s , ’ b , ’ a s ) max l e t rec max : type a b c . ( a , b , c ) max → a → b → c = fun mx m n → match mx,m with MaxEq R e f l , → m | MaxFlip mx’ , → max mx’ n m | MaxSuc mx’ , S m’ → S (max mx’ m’ n)

Type refinement In the MaxEq branch: a ≡ b, a ≡ c m : c In the MaxFlip branch: no refinement In the MaxSuc branch: a ≡ d s, c ≡ d s (for some d) mx’ : (d, b, d) max m’ : d max mx’ m’ n : d

37/ 49

slide-39
SLIDE 39

Functions on depth-annotated trees

v a l ? : ( ’ a , ’ n) dtree → ’n v a l ? : ( ’ a , ’ n s ) dtree → ’ a v a l ? : ( ’ a , ’ n) dtree → ( ’ a , ’ n) dtree

38/ 49

slide-40
SLIDE 40

Depth-annotated trees: depth

T[3] max(2,0)≡2 (p1) T[2] max(1,0)≡1 (p2) T[1] max(0,0)≡0 (p3) E a E b E c E

S (max p1 (S (max p2 (S (max p3 Z Z)) Z)) Z) l e t rec depthD : type a n . ( a , n) dtree → n = f u n c t i o n EmptyD → Z | TreeD ( l , , r ,mx) → S (max mx ( depthD l ) ( depthD r ))

39/ 49

slide-41
SLIDE 41

Depth-annotated trees: top

T[3] max(2,0)≡2 (p1) T[2] max(1,0)≡1 (p2) T[1] max(0,0)≡0 (p3) E a E b E c E

c l e t topD : type a n . ( a , n s ) dtree → a = f u n c t i o n TreeD ( , v , , ) → v

40/ 49

slide-42
SLIDE 42

Depth-annotated trees: swivel

T[2] max(1,0)≡1 T[1] max(0,0)≡0 E a E b E T[2] max(0,1)≡1 E b T[1] max(0,0)≡0 E a E

l e t rec swivelD : type a n . ( a , n) dtree → (a , n) dtree = f u n c t i o n EmptyD → EmptyD | TreeD ( l , v , r ,m) → TreeD ( swivelD r , v , swivelD l , MaxFlip m)

41/ 49

slide-43
SLIDE 43

Efficiency

42/ 49

slide-44
SLIDE 44

Efficiency: missing branches

l e t top : ’ a . ’ a t r e e → ’ a option = f u n c t i o n Empty → None | Tree ( , v , ) → Some v (function p (* ocaml -dlambda *) (if p (makeblock 0 (field 1 p)) 0a)) l e t topG : type a n . ( a , n s ) g t r e e → a = f u n c t i o n TreeG ( , v , ) → v (function p (* ocaml -dlambda *) (field 1 p))

43/ 49

slide-45
SLIDE 45

Efficiency: zips

l e t rec zipTree : type a n . ( a , n) g t r e e → (a , n) g t r e e → ( a ∗ a , n) g t r e e = fun x y → match x , y with EmptyG , EmptyG → EmptyG | TreeG ( l , v , r ) , TreeG (m,w, s ) → TreeG ( zipTree l m, ( v ,w) , zipTree r s ) (letrec (* ocaml -dlambda *) (zipTree (function x y (if x (makeblock 0 (apply zipTree (field 0 x) (field 0 y)) (makeblock 0 (field 1 x) (field 1 y)) (apply zipTree (field 2 x) (field 2 y))) 0a))) (apply (field 1 (global Toploop!)) "zipTree" zipTree))

44/ 49

slide-46
SLIDE 46

Adverts Reflection without Remorse (Oleg Kiselyov)

3pm-4pm Monday 9th, SS03

OCaml compiler hacking

6pm-10pm Tuesday 10th, FW11 6.30pm Generating code with polymorphic let (Oleg Kiselyov) 7pm Pizza 7.30pm Delve into OCaml internals

45/ 49