Arity-Generic Datatype-Generic Programming

Arity-Generic Datatype-Generic Programming

Arity-Generic Datatype-Generic Programming Chris Casinghino Stephanie Weirich University of Pennsylvania January 19, 2010 PLPV, Madrid 1/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 2/32 Datatype-Genericity Datatype-generic functions can be implemented for many datatypes. list-map :(a ! b) ! [a] ! [b] maybe-map :(a ! b) ! Maybea ! Maybeb pair-map :(a1 ! a2) ! (b1 ! b2) ! (a1; b1) ! (a2; b2) 3/32 Arity-Genericity Arity-generic functions can be implemented at many arities. At higher arities, map is often called zip. The Haskell standard library includes: repeat : a ! [a] map :(a ! b) ! [a] ! [b] zipWith :(a ! b ! c) ! [a] ! [b] ! [c] zipWith3 :(a ! b ! c ! d) ! [a] ! [b] ! [c] ! [d] 4/32 Doubly Generic Functions • Some functions, like map, are doubly generic. pair-map1 : a1 ! a2 ! (a1; a2) maybe-map2 :(a ! b) ! Maybea ! Maybeb list-map3 :(a ! b ! c) ! [a] ! [b] ! [c] ... • Goal: one function, ngmap, which produces any of these denitions from an arity and a type. For example: ngmap2 Maybe :(a ! b) ! Maybea ! Maybeb • Importantly, the notion of arity already appears in datatype-generic programming (but not arity-genericity). 5/32 Motivation Why study doubly generic functions? • They can reduce boilerplate. • We may be able to prove properties generally for all instances of doubly generic functions. • New insight into the nature of operations like map. • Formally specifying a framework for them helps us nd more. 6/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 7/32 Dierent Types at Dierent Kinds • Consider equality functions for various types: nat-eq : N ! N ! Bool list-eq : 8 a : (a ! a ! Bool) ! [a] ! [a] ! Bool pair-eq : 8 ab : (a ! a ! Bool) ! (b ! b ! Bool) ! (a; b) ! (a; b) ! Bool • Generic Haskell style datatype-generic programs have kind-indexed types. Eq h?i t = t ! t ! Bool Eq hk1 ) k2i t = 8 a : Eq hk1i a ! Eq hk2i (ta ) • The kind-indexed type Eq has arity one, because it takes one type argument. 8/32 Kind-indexed Types for Maps • On the other hand, datatype-generic map has a kind-indexed type of arity two. Map h?i t1 t2 = t1 ! t2 Map hk1 ) k2i t1 t2 = 8 ab : Map hk1i ab ! Map hk2i (t1 a)(t2 b) • Datatype-generic zipWith has a kind-indexed type of arity three. Zip h?i t1 t2 t3 = t1 ! t2 ! t3 Zip hk1 ) k2i t1 t2 t3 = 8 abc : Zip hk1i abc ! Zip hk2i (t1 a)(t2 b)(t3 c) • These two look very similar... 9/32 Summary • Arities already show up in standard kind-indexed types. • Some frameworks for datatype-generic programming support dierent arities (but not generalizing over the arity). • New observation: when written in dependently-typed languages, they can support arity-genericity too. 10/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 11/32 Universes • In dependently typed languages (like Agda), generic programming frameworks are implemented using universes. • A universe is: • A data structure to represent part of the type language • And an interpretation function to convert members of the datatype to actual Agda types. • A generic program is dened by recursion over the universe. • Our universe is based on the type language of F !it's essentially STLC. 12/32 Kinds • We dene a data type to represent kinds, and a function to interpret its members (the codes) as Agda kinds. data Kind : Set where ? : Kind _)_ : Kind ! Kind ! Kind _ : Kind ! Set J ?K = Set J a )K b = a ! b J K J K J K • Set is the classier of Agda types. We'll gloss over some details of the type hierarchy. 13/32 Type Constants Type constants are indexed by their kinds. data Const : Kind ! Set where Unit : Const ? Nat : Const ? Sum : Const (? ) ? ) ?) Prod : Const (? ) ? ) ?) interp-c : 8f kg! Constk ! k interp-c Unit = > J K interp-c Nat = N interp-c Sum = _]_ interp-c Prod = _×_ 14/32 Types • Types comprise variables, functions, applications, and constants. data Ty : Ctx ! Kind ! Set where Var : ... Lam : ... App : ... Con : ... • We have a function for interpreting closed Types: b_c : 8f kg! Ty [] k ! k J K 15/32 Example • As an example, we might dene an Option type in Agda, isomorphic to the standard datatype: Option : Set ! Set Option = λ A !>] A • We can represent it with a code: option : Ty [](? ) ?) option = Lam (App (App (Con Sum)(Con Unit)) (VarVZ )) • Agda can see that b option c normalizes to Option. 16/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 17/32 Preliminaries • We need just two more things. • Agda's library has length indexed vectors: data Vec (A : Set): N ! Set where []: VecA zero _::_ : 8f ng (a : A)(xs : VecAn ) ! VecA (sucn ) • We dene_ ~_, pronounced zap, a zipping application on vectors: _~_ : fAB : Setg fn : Ng ! Vec (A ! B) n ! VecAn ! VecBn • And repeat, which createsn copies of a term: repeat : fA : Setg! (n : N) ! A ! VecAn 18/32 Kind-indexed Types revisited • Observe that the kind-indexed types we saw before have a very regular form: Eq h?i t = t ! t ! Bool Eq hk1 ) k2i t = 8 a : Eq hk1i a ! Eq hk2i (ta ) Map h?i t1 t2 = t1 ! t2 Map hk1 ) k2i t1 t2 = 8 ab : Map hk1i ab ! Map hk2i (t1 a)(t2 b) • At kind ?, they use the type argument(s) in an operation-specic way. • At arrow kinds they are logical and completely regular. 19/32 Kind-indexed Types, formally • So, we can derive instances of kind-indexed types automatically if provided with the denition at base kinds: _h_i_ : fn : Ng! (b : Vec Setn ! Set) ! (k : Kind) ! Vec k n ! Set J K b h ? i v = bv b h k1 ) k2 i v = (a : Vec k1 ) ! b h k1 i a ! b h k2 i (v ~ a) J K • Since the number of type arguments is variable, we take them as a vector. • In the development, this denition is then curried so users can supply the types individually. 20/32 Example: GMap • Datatype-generic map has arity two. Its base type is: GMap :(v : Vec Set2 ) ! Set GMap (A::B:: [ ]) = A ! B • GMap h? ) ?i (repeat2 List ) normalizes to: 8f AB : Setg! (A ! B) ! ListA ! ListB • GMap h? ) ? ) ?i (repeat2_ ×_) normalizes to: 8f A1 B1 : Setg! (A1 ! B1) !f A2 B2 : Setg! (A2 ! B2) ! (A1 × A2) ! (B1 × B2) 21/32 The Framework • Users implement the operation for type constants by constructing a TyConstEnvb TyConstEnvb = fk : Kindg (c : Constk ) ! b h k i (repeat b Conc c) • Then they call ngen: ngen : fn : Ng fb : Vec Setn ! Setg fk : Kindg ! (TyConstEnvb ) ! (t : Ty [] k) ! b h k i (repeatn b t c) 22/32 Map's TyConstEnv • We've already dened datatype-generic map's type. • Now, its TyConstEnv. gmap-const : TyConstEnv GMap gmap-const Nat = λ x ! x gmap-const Unit = λ x ! x gmap-const Prod = λ f1 f2x ! (f1 (proj1 x); f2 (proj2 x)) gmap-const Sum = g where g : fA1 B1 A2B2 : Setg ! (A1 ! B1) ! (A2 ! B2) ! A1 ] A2 ! B1 ] B2 g fa fb (inj1 xa) = inj1 (fa xa) g fa fb (inj2 xb) = inj2 (fb xb) 23/32 Datatype-Generic Map • With gmap-const, we can dene datatype-generic map: gmap : fk : Kindg! (t : Ty [] k) ! GMap h k i (b t c :: b t c :: [ ]) gmapt = ngen gmap-constt • For example: option-map : fAB : Setg! (A ! B) ! OptionA ! OptionB option-map = gmap option • Using generic functions at actual Agda datatypes is discussed in the paper. 24/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 25/32 Writing Arity-Generic Programs • All the pieces of the framework are parameterized by arity: _h_i_ : fn : Ng! (b : Vec Setn ! Set) ! (k : Kind) ! Vec k n ! Set J K TyConstEnv : fn : Ng! (b : Vec Setn ! Set) ! Set ngen : fn : Ng fb : Vec Setn ! Setg fk : Kindg ! (TyConstEnvb ) ! (t : Ty [] k) ! b h k i (repeatn b t c)) • So, if we deneb and the TyConstEnv while leaving the arity general, we can get out an arity-generic denition. 26/32 Arity-Generic Map • So, we want to dene arity-generic map's base type and TyConstEnv for any arity: NGmap : fn : Ng! Vec Setn ! Set NGmap Ts = see the paper! ngmap-const : fn : Ng! TyConstEnv fng NGmap ngmap-const fng c = see the paper! • With these, we can get arity-generic map directly from ngen. ngmap : fk : Kindg! (n : N) ! (t : Ty [] k) ! NGmap h k i (repeatn b t c) ngmapnt = ngen ngmap-constt 27/32 Examples with ngmap For example, maps and zips on products are instances of ngmap: pair-map1 : fAB : Setg! A ! B ! A × B pair-map1 = ngmap1 (Con Prod) pair-map2 : fA1 B1 A2B2 : Setg ! (A1 ! B1) ! (A2 ! B2) ! A1 × A2 ! B1 × B2 pair-map2 = ngmap2 (Con Prod) pair-map3 : fA1 B1 C1 A2 B2 C2 : Setg ! (A1 ! B1 ! C1) ! (A2 ! B2 ! C2) ! A1 × A2 ! B1 × B2 ! C1 × C2 pair-map3 = ngmap3 (Con Prod) 28/32 Outline 1 Motivation 2 Arities in Datatype-Generic Programming 3 A Universe for Generic Programming 4 The Framework 5 Arity-Generic Map 6 Conclusion 29/32 Conclusion Also in the paper: • More arity-generic programs (equality, unzip, folds).

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    32 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us