last time gadts
play

Last time: GADTs a b 1/ 48 This time: GADT programming patterns - PowerPoint PPT Presentation

Last time: GADTs a b 1/ 48 This time: GADT programming patterns 2/ 48 Recapitulation 3/ 48 Recapitulation: technical GADT type indexes vary across constructors. We have families of types: a type per nat, per tree depth, etc. GADTs need


  1. Last time: GADTs a ≡ b 1/ 48

  2. This time: GADT programming patterns 2/ 48

  3. Recapitulation 3/ 48

  4. Recapitulation: technical GADT type indexes vary across constructors. We have families of types: a type per nat, per tree depth, etc. GADTs need machinery from earlier lectures: existentials, polymorphic recursion, non-regularity. GADTs are about type equalities (and sometimes inequalities). Type equalities are revealed by examining data. Compilers use the richer types to generate better code. 4/ 48

  5. Recapitulation: philosophical Phantom types protect abstractions against misuse. GADTs also protect definitions. GADTs lead to rich types which can be viewed as propositions. Descriptive data types lead to useful function types. 5/ 48

  6. Equality 6/ 48

  7. Recall: equality in System F ω Eq = λα : : ∗ . λβ : : ∗ . ∀ φ : : ∗ ⇒∗ . φ α → φ β r e f l : ∀ α : : ∗ . Eq α α r e f l = Λ α : : ∗ . Λ φ : : ∗ ⇒∗ . λ x : φ α . x symm : ∀ α : : ∗ . ∀ β : : ∗ . Eq α β → Eq β α symm = Λ α : : ∗ . Λ β : : ∗ . λ e : ( ∀ φ : : ∗ ⇒∗ . φ α → φ β ) . e [ λγ : : ∗ . Eq γ α ] ( r e f l [ α ] ) t r a n s : ∀ α : : ∗ . ∀ β : : ∗ . ∀ γ : : ∗ . Eq α β → Eq β γ → Eq α γ t r a n s = Λ α : : ∗ . Λ β : : ∗ . Λ γ : : ∗ . λ ab : Eq α β . λ bc : Eq β γ . bc [ Eq α ] ab 7/ 48

  8. Equlity with GADTs type ( , ) e q l = R e f l : ( ’ a , ’ a ) e q l r e f l : ( ’ a , ’ a ) e q l val val symm : ( ’ a , ’ b) e q l → ( ’ b , ’ a ) e q l val t r a n s : ( ’ a , ’ b) e q l → ( ’ b , ’ c ) e q l → ( ’ a , ’ c ) e q l module L i f t (T : sig type t end ) : sig l i f t : ( ’ a , ’ b) e q l → ( ’ a T. t , ’ b T. t ) e q l val end val cast : ( ’ a , ’ b) e q l → ’ a → ’b 8/ 48

  9. Building GADTs from algebraic types and equality 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 type ( ’ a , ’ n) e t r e e = EmptyE : ( z , ’ n) e q l → ( ’ a , ’ n) e t r e e | TreeE : ( ’ n , ’m s ) e q l ∗ ( ’ a , ’m) e t r e e ∗ ’ a ∗ ( ’ a , ’m) e t r e e → ( ’ a , ’ n) e t r e e 9/ 48

  10. Building GADTs from algebraic types and equality 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 ) 10/ 48

  11. Building GADTs from algebraic types and equality 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 (* n = z *) | TreeG ( l , , ) → S ( depthG l ) 10/ 48

  12. Building GADTs from algebraic types and equality 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 (* n = z *) | TreeG ( l , , ) → S ( depthG l ) (* n = m s *) 10/ 48

  13. Building GADTs from algebraic types and equality type ( ’ a , ’ n) e t r e e = EmptyE : ( ’ n , z ) e q l → ( ’ a , ’ n) e t r e e | TreeE : ( ’ n , ’m s ) e q l ∗ ( ’ a , ’m) e t r e e ∗ ’ a ∗ ( ’ a , ’m) e t r e e → ( ’ a , ’ n) e t r e e l e t rec depthE : type a n . ( a , n) e t r e e → n = f u n c t i o n EmptyE R e f l → Z | TreeE ( Refl , l , , ) → S ( depthE l ) 11/ 48

  14. Building GADTs from algebraic types and equality type ( ’ a , ’ n) e t r e e = EmptyE : ( ’ n , z ) e q l → ( ’ a , ’ n) e t r e e | TreeE : ( ’ n , ’m s ) e q l ∗ ( ’ a , ’m) e t r e e ∗ ’ a ∗ ( ’ a , ’m) e t r e e → ( ’ a , ’ n) e t r e e l e t rec depthE : type a n . ( a , n) e t r e e → n = f u n c t i o n EmptyE R e f l → Z (* n = z *) | TreeE ( Refl , l , , ) → S ( depthE l ) 11/ 48

  15. Building GADTs from algebraic types and equality type ( ’ a , ’ n) e t r e e = EmptyE : ( ’ n , z ) e q l → ( ’ a , ’ n) e t r e e | TreeE : ( ’ n , ’m s ) e q l ∗ ( ’ a , ’m) e t r e e ∗ ’ a ∗ ( ’ a , ’m) e t r e e → ( ’ a , ’ n) e t r e e l e t rec depthE : type a n . ( a , n) e t r e e → n = f u n c t i o n EmptyE R e f l → Z (* n = z *) | TreeE ( Refl , l , , ) → S ( depthE l ) (* n = m s *) 11/ 48

  16. GADT programming patterns 12/ 48

  17. A new example: representing (some) JSON JSON values json ::= true | f a l s e | string | number | n u l l [ ] | [ json-seq ] {} | { json-kvseq } json-seq ::= json , json-seq json json-kvseq ::= string : json string : json , string : json-kvseq 13/ 48

  18. A new example: representing (some) JSON JSON values json ::= true | f a l s e | string | number | n u l l [ ] | [ json-seq ] json-seq ::= json , json-seq json A JSON value [ ”one ” , true , 3.4 , [ [ ” four ” ] , [ n u l l ] ] ] 14/ 48

  19. An “untyped” JSON representation type ujson = UStr : s t r i n g → ujson | UNum : f l o a t → ujson | UBool : bool → ujson | UNull : ujson | UArr : ujson l i s t → ujson [ ”one ” , true , 3.4 , [ [ ” four ” ] , [ n u l l ] ] ] UArr [ UStr ”one ”; UBool true ; UNum 3 . 4 ; UArr [ UArr [ UStr ” four ” ] ; UArr [ UNull ] ] ] 15/ 48

  20. Pattern : Richly typed data Data may have finer structure than algebraic data types can express. GADT indexes allow us to specify constraints more precisely. 16/ 48

  21. Richly typed data type t j s o n = Str : s t r i n g → s t r i n g t j s o n | Num : f l o a t → f l o a t t j s o n | Bool : bool → bool t j s o n | Null : u n i t t j s o n | Arr : ’ a t a r r → ’ a t j s o n and t a r r = N i l : u n i t t a r r | : : : ’ a t j s o n ∗ ’b t a r r → ( ’ a ∗ ’b) t a r r Arr ( Str ”one” : : Bool true : : Num 3.4 : : Arr ( Arr ( Str ” four ” : : N i l ) : : Null : : N i l ) : : N i l ) 17/ 48

  22. Richly typed data ( ∗ negate a l l the bools in a JSON value ∗ ) l e t rec unegate : ujson → ujson = . . . ( ∗ negate a l l the bools in a JSON value ∗ ) l e t rec negate : type a . a t j s o n → a t j s o n = f u n c t i o n Bool true → Bool f a l s e | Bool f a l s e → Bool true | Arr a r r → Arr ( n e g a t e a r r a r r ) | v → v and n e g a t e a r r : type a . a t a r r → a t a r r = f u n c t i o n N i l → N i l | j : : j s → negate j : : n e g a t e a r r j s 18/ 48

  23. Pattern : Building GADT values It’s not always possible to determine index types statically. For example, the depth of a tree might depend on user input. 19/ 48

  24. Building GADT values: two approaches How might a function make t build a value of a GADT type t ? l e t make t : type a . s t r i n g → a t = . . . 20/ 48

  25. Building GADT values: two approaches How might a function make t build a value of a GADT type t ? l e t make t : type a . s t r i n g → a t = ✗ 20/ 48

  26. Building GADT values: two approaches How might a function make t build a value of a GADT type t ? l e t make t : type a . s t r i n g → a t = ✗ With existentials make t builds a value of type ’a t for some ’a. 20/ 48

  27. Building GADT values: two approaches How might a function make t build a value of a GADT type t ? l e t make t : type a . s t r i n g → a t = ✗ With existentials make t builds a value of type ’a t for some ’a. With universals the caller of make t must accept ’a t for any ’a. 20/ 48

  28. Building GADT values with existentials type e t j s o n = ETJson : ’ a t j s o n → e t j s o n type e t a r r = ETArr : ’ a t a r r → e t a r r l e t rec t j s o n o f u j s o n : ujson → e t j s o n = f u n c t i o n UStr s → ETJson ( Str s ) | UNum u → ETJson (Num u) | UBool b → ETJson ( Bool b) | UNull → ETJson Null | UArr a r r → l e t ETArr arr ’ = t a r r o f u a r r a r r in ETJson ( Arr arr ’ ) and t a r r o f u a r r : ujson l i s t → e t a r r = f u n c t i o n [ ] → ETArr N i l | j : : j s → l e t ETJson j ’ = t j s o n o f u j s o n j in l e t ETArr js ’ = t a r r o f u a r r j s in ETArr ( j ’ : : js ’ ) 21/ 48

  29. Building GADT values with existentials type e t j s o n = ETJson : ’ a t j s o n → e t j s o n type e t a r r = ETArr : ’ a t a r r → e t a r r l e t rec t j s o n o f u j s o n : ujson → e t j s o n = f u n c t i o n UStr s → ETJson ( Str s ) (* Str s : string tjson *) | UNum u → ETJson (Num u) | UBool b → ETJson ( Bool b) | UNull → ETJson Null | UArr a r r → l e t ETArr arr ’ = t a r r o f u a r r a r r in ETJson ( Arr arr ’ ) and t a r r o f u a r r : ujson l i s t → e t a r r = f u n c t i o n [ ] → ETArr N i l | j : : j s → l e t ETJson j ’ = t j s o n o f u j s o n j in l e t ETArr js ’ = t a r r o f u a r r j s in ETArr ( j ’ : : js ’ ) 21/ 48

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