last time abstraction and parametricity
play

Last time: abstraction and parametricity 1/ 44 This time: GADTs - PowerPoint PPT Presentation

Last time: abstraction and parametricity 1/ 44 This time: GADTs a b 2/ 44 What we gain : : (Addtionally, some programs become faster!) 3/ 44 What we gain : : (Addtionally, some


  1. Last time: abstraction and parametricity ∃ ∀ 1/ 44

  2. This time: GADTs a ≡ b 2/ 44

  3. What we gain Γ ⊢ : ⇓ Γ ⊢ : ⇓ (Addtionally, some programs become faster!) 3/ 44

  4. What we gain Γ ⊢ : ⇓ Γ ⊢ : ⇓ (Addtionally, some programs become faster!) 3/ 44

  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/ 44

  6. What we’ll write Non-regularity in constructor return types type _ t = T : t 1 → t 2 t Locally abstract types : let f : type a b . a t → b t = function . . . let g ( type a ) ( type b ) (x : a t) : b t = . . . 5/ 44

  7. Nested types 6/ 44

  8. Unconstrained trees T T c E T b E E a E type ’a tree = Empty : ’a tree | Tree : ’a tree * ’a * ’a tree → ’a tree 7/ 44

  9. Functions on unconstrained trees val ? : ’a tree → int val ? : ’a tree → ’a option val ? : ’a tree → ’a tree 8/ 44

  10. Unconstrained trees: depth T 1 + max (1 + max T c E (1 + max 0 0) T b E 0) 0 E a E let rec depth : ’a.’a tree → int = function Empty → 0 | Tree (l,_,r) → 1 + max (depth l) (depth r) 9/ 44

  11. Unconstrained trees: top T Some c T c E T b E E a E let top : ’a.’a tree → ’a option = function Empty → None | Tree (_,v,_) → Some v 10/ 44

  12. Unconstrained trees: swivel T T T c E E c T T b E E b T E a E E a E let rec swivel : ’a.’a tree → ’a tree = function Empty → Empty | Tree (l,v,r) → Tree (swivel r, v, swivel l) 11/ 44

  13. Perfect leaf trees via nesting S S S Z e f g h a b c d type ’a perfect = ZeroP : ’a → ’a perfect | SuccP : (’a * ’a) perfect → ’a perfect 12/ 44

  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/ 44

  15. Functions on perfect nested trees val ? : ’a ntree → int val ? : ’a ntree → ’a option val ? : ’a ntree → ’a ntree 14/ 44

  16. Perfect trees: depth T a 1 + 1 + T 1 + (b, c) 0 T ((d, e), (f, g)) E let rec depthN : ’a.’a ntree → int = function EmptyN → 0 | TreeN (_,t) → 1 + depthN t 15/ 44

  17. Perfect trees: top T a Some a T (b, c) T ((d, e), (f, g)) E let rec topN : ’a.’a ntree → ’a option = function EmptyN → None | TreeN (v,_) → Some v 16/ 44

  18. Perfect trees: swivel T T a a T T (b, c) (c, b) T T ((d, e), (f, g)) ((g, f), (e, d)) E E let 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) let swivelN p = swiv id p 17/ 44

  19. GADTs 18/ 44

  20. Perfect trees, take two T[3] T[2] a T[2] T[1] c T[1] T[1] b T[1] E f E E g E E d E E e E type (’a, _) gtree = EmptyG : (’a,z) gtree | TreeG : (’a,’n) gtree * ’a * (’a,’n) gtree → (’a,’n s) gtree 19/ 44

  21. Natural numbers type z = Z type _ s = S : ’n → ’n s # let zero = Z;; val zero : z = Z # let three = S (S (S Z));; val three : z s s s = S (S (S Z)) 20/ 44

  22. Functions on perfect trees (GADTs) val ? : (’a,’n) gtree → ’n val ? : (’a,’n s) gtree → ’a val ? : (’a,’n) gtree → (’a,’n) gtree 21/ 44

  23. Perfect trees (GADTs): depth T[2] S (depth S (depth T[1] b T[1] Z)) E e E E d E let rec depthG : type a n.(a, n) gtree → n = function EmptyG → Z | TreeG (l,_,_) → S (depthG l) 22/ 44

  24. Perfect trees (GADTs): depth type (’a, _) gtree = EmptyG : (’a,z) gtree | TreeG : (’a,’n) gtree * ’a * (’a,’n) gtree → (’a,’n s) gtree let rec depthG : type a n.(a, n) gtree → n = function EmptyG → Z | TreeG (l,_,_) → S (depthG l) Type refinement In the EmptyG branch: n ≡ z In the TreeG branch: (for some m ) n ≡ m s l : (a, m)gtree depthG l : m Polymorphic recursion The argument to the recursive call has size m (s.t. s m ≡ n ) 23/ 44

  25. Perfect trees (GADTs): top T[2] a T[1] a T[1] E c E E b E let topG : type a n.(a,n s) gtree → a = function TreeG (_,v,_) → v 24/ 44

  26. Perfect trees (GADTs): depth type (’a, _) gtree = EmptyG : (’a,z) gtree | TreeG : (’a,’n) gtree * ’a * (’a,’n) gtree → (’a,’n s) gtree let topG : type a n.(a,n s) gtree → a = function TreeG (_,v,_) → v Type refinement In an EmptyG branch we would have: n s ≡ z — impossible! 25/ 44

  27. Perfect trees (GADTs): swivel T[2] T[2] T[1] a T[1] T[1] a T[1] E c E E c E E b E E b E let rec swivelG : type a n.(a,n) gtree → (a,n) gtree = function EmptyG → EmptyG | TreeG (l,v,r) → TreeG (swivelG r, v, swivelG l) 26/ 44

  28. Perfect trees (GADTs): swivel type (’a, _) gtree = EmptyG : (’a,z) gtree | TreeG : (’a,’n) gtree * ’a * (’a,’n) gtree → (’a,’n s) gtree let rec swivelG : type a n.(a,n) gtree → (a,n) gtree = function EmptyG → EmptyG | TreeG (l,v,r) → TreeG (swivelG r, v, swivelG l) Type refinement In the EmptyG branch: n ≡ z In the TreeG branch: (for some m ) n ≡ m s 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/ 44

  29. Zipping perfect trees T[2] T[2] T[1] a T[1] T[1] (a,d) T[1] E c E E b E T[2] E (b,e) E E (c,f) E T[1] d T[1] E f E E e E let rec zipTree : type a b n.(a,n) gtree → (b,n) gtree → (a * b,n) gtree = 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/ 44

  30. Zipping perfect trees type (’a, _) gtree = EmptyG : (’a,z) gtree | TreeG : (’a,’n) gtree * ’a * (’a,’n) gtree → (’a,’n s) gtree let rec zipTree : type a b n.(a,n) gtree → (b,n) gtree → (a * b,n) gtree = 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: (for some m ) n ≡ m s EmptyG, TreeG _ produces and n ≡ z n ≡ m s — impossible! 29/ 44

  31. Conversions between perfect tree representations T a T[2] T T[1] a T[1] (b, c) E b E E c E E let rec nestify : type a n.(a,n) gtree → a ntree = function EmptyG → EmptyN | TreeG (l, v, r) → TreeN (v, nestify (zipTree l r)) 30/ 44

  32. Depth-annotated trees T[2] max(1,0) ≡ 1 T[1] b E max(0,0) ≡ 0 E a E type (’a,_) dtree = EmptyD : (’a,z) dtree | TreeD : (’a,’m) dtree * ’a * (’a,’n) dtree * (’m,’n,’o) max → (’a,’o s) dtree 31/ 44

  33. The untyped maximum function val max : ’a → ’a → ’a Parametricity: max is one of fun x _ → x fun _ y → y 32/ 44

  34. A typed maximum function val max : (’a,’b,’c) max → ’a → ’b → ’c (max (a,b) ≡ c) → a → b → c 33/ 44

  35. A typed maximum function: a max predicate type (_,_,_) max = MaxEq : (’a,’a,’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 34/ 44

  36. A typed maximum function type (_,_) eql = Refl : (’a,’a) eql type (_,_,_) max = MaxEq : (’a,’a,’a) max | MaxFlip : (’a,’b,’c) max → (’b,’a,’c) max | MaxSuc : (’a,’b,’a) max → (’a s,’b,’a s) max let rec max : type a b c.(a,b,c) max → a → b → c = fun mx m n → match mx ,m with MaxEq , _ → m | MaxFlip mx ’, _ → max mx ’ n m | MaxSuc mx ’ , S m’ → S (max mx ’ m’ n) 35/ 44

  37. A typed maximum function type (_,_,_) max = MaxEq : (’a,’a,’a) max | MaxFlip : (’a,’b,’c) max → (’b,’a,’c) max | MaxSuc : (’a,’b,’a) max → (’a s,’b,’a s) max let rec max : type a b c.(a,b,c) max → a → b → c = fun mx m n → match mx ,m with MaxEq , _ → 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 36/ 44

  38. Functions on depth-annotated trees val ? : (’a,’n) dtree → ’n val ? : (’a,’n s) dtree → ’a val ? : (’a,’n) dtree → (’a,’n) dtree 37/ 44

  39. Depth-annotated trees: depth T[3] S (max p 1 max(2,0) ≡ 2 ( p 1 ) (S (max p 2 (S (max p 3 Z Z)) T[2] c E Z)) max(1,0) ≡ 1 ( p 2 ) Z) T[1] b E max(0,0) ≡ 0 ( p 3 ) E a E let rec depthD : type a n.(a,n) dtree → n = function EmptyD → Z | TreeD (l,_,r,mx) → S (max mx (depthD l) (depthD r)) 38/ 44

  40. Depth-annotated trees: top T[3] c max(2,0) ≡ 2 ( p 1 ) T[2] c E max(1,0) ≡ 1 ( p 2 ) T[1] b E max(0,0) ≡ 0 ( p 3 ) E a E let topD : type a n.(a,n s) dtree → a = function TreeD (_,v,_,_) → v 39/ 44

  41. Depth-annotated trees: swivel T[2] T[2] max(1,0) ≡ 1 max(0,1) ≡ 1 T[1] b E E b T[1] max(0,0) ≡ 0 max(0,0) ≡ 0 E a E E a E let rec swivelD : type a n.(a,n) dtree → (a,n) dtree = function EmptyD → EmptyD | TreeD (l,v,r,m) → TreeD (swivelD r, v, swivelD l, MaxFlip m) 40/ 44

  42. Next time GADTs in practice 41/ 44

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend