230 likes | 343 Vues
This paper presents an innovative extension for the Clean programming language, focusing on generic programming techniques. It covers the foundational principles of generics, their implementation in Clean, and how to create customized instances for various data types. Key topics include mapping functions, defining equality, and the representation of generic types such as lists and trees. The paper also discusses instance specialization, challenges faced during the implementation, and offers practical examples to illustrate the proposed methodologies. This extension aims to enhance code reusability and maintainability within the Clean programming environment.
E N D
A Generic Programming Extension for Clean Artem Alimarine and Rinus Plasmeijer University of Nijmegen
Contents (1) • Introduction to generic programming • Generics in Clean • Customized instances • Conclusion A Generic Programming Extension for Clean
Generic programming (1) • Functions are defined by induction on the structure of data types. • Defined once, specialized for an arbitrary data type. • Examples: • Equality, lex. comparison, unification. • Mapping, zipping, folding. • Pretty printers and parsers. A Generic Programming Extension for Clean
Generic programming (2) mapList f List a List b fromList toList gmap f Generic a Generic b fromRose toRose mapRose f Rose a Rose b A Generic Programming Extension for Clean
Generic type representation • Example types :: List a = Nil | Cons a (List a) :: Rose a = Rose a (List (Rose a)) :: Tree a b = Tip a | Bin b (Tree a b) (Tree a b) • Binary sums and products (in generic prelude) :: UNIT = UNIT :: PAIR a b = PAIR a b :: EITHER a b = LEFT a | RIGHT b • Generic type representations :: ListG a :== EITHER UNIT (PAIR a (List a)) :: RoseG a :== PAIR a (List (Rose a)) :: TreeG a b :== EITHER a (PAIR b (PAIR (Tree a b) (Tree a b))) A Generic Programming Extension for Clean
Generic equality class eq t :: t t Bool instance eq Int where eq x y = eqInt x y instance eq UNIT where eq x y = True instance eq (EITHER a b) | eq a & eq b where eq (LEFT x) (LEFT y) = eq x y eq (RIGHT x) (RIGHT y) = eq x y eq _ _ = False instance eq (PAIR a b) | eq a & eq b where eq (PAIR x1 x2) (PAIR y1 y2) = eq x1 y1 && eq x2 y2 A Generic Programming Extension for Clean
Specialization instance eq (List a) | eq a where eq x y = eq (fromList x) (fromList y) instance eq (Rose a) | eq a where eq x y = eq (fromRose x) (fromRose y) instance eq (Tree a b) | eq a & eq b where eq x y = eq (fromTree x) (fromTree y) A Generic Programming Extension for Clean
Generic mapping • Mapping class map t :: (a b) (t a) (t b) • Specialization for lists instance map List where map f x = toList (map f (fromList x)) • Problems • Instances on UNIT, PAIR and EITHER cannot be defined: the kinds do not match instance map UNIT where map f x = x • This mapping function is defined only for kind **. A Generic Programming Extension for Clean
Contents (2) • Introduction to Generic programming • Generics in Clean • Customized instances • Conclusion A Generic Programming Extension for Clean
Our approach • Based on two approaches: • Derivable type classes of Hinze and P. Jones • Generic definition of class members • Limited to classes with class variables of kind * • Kind-indexed types of Hinze • One generic function works for types of all kinds • Overloaded functions cannot be defined generically • One generic function works for all kinds • Overloaded functions can be defined generically A Generic Programming Extension for Clean
Instances to generate instance map List generic instance map Rose generic instance map Tree generic instance map (,) generic instance map (,,) generic :: Sequ a = SequEmpty | SequZero (Sequ (a,a)) | SequOne a (Sequ (a,a)) instance map Sequ generic A Generic Programming Extension for Clean
Definition of generic mapping generic map a b :: a b instance map Int where map x = x instance map UNIT where map x = x instance map PAIR where map mapx mapy (PAIR x y) = PAIR (mapx x)(mapy y) instance map EITHER where map mapl mapr (LEFT x) = LEFT (mapl x) map mapl mapr (RIGHT x) = RIGHT (mapr x) A Generic Programming Extension for Clean
Translation: kind indexed classes • Generic definition generic map a b :: a b • Translated to a kind-indexed family of classes class map* t :: t t class map** t :: (a b) (t a) t b class map*** t :: (a1b1) (a2b2) (t a1 a2) t b1 b2 … • Each class has • One class variable • One class member with the member type derived from the generic type A Generic Programming Extension for Clean
Translation: instances are bound to classes • Instances of the generic definition instance map*Int where map* x = x instance map*UNIT where map* x = x instance map***PAIR where map*** mapx mapy (PAIR x y) = PAIR (mapx x)(mapy y) instance map***EITHER where map*** mapl mapr (LEFT x) = LEFT (mapl x) map*** mapl mapr (RIGHT x) = RIGHT (mapr x) • Instances to generate instance map**List generic instance map***Tree generic A Generic Programming Extension for Clean
Translation: instance for lists • Generic representation of lists :: ListG a :== EITHER UNIT (PAIR a (List a)) • Instance to generate instance map**List generic • Generated instance for lists instance map**Listwhere map** f x = toList (mapListG f (fromList x)) mapListG :: (a b) (ListG a) ListG b mapListG f = map*** map* (map*** f (map** f)) • After resolving overloading mapListG f = mapEITHER mapUNIT (mapPAIR f (mapList f)) A Generic Programming Extension for Clean
Translation: instance for trees • Generic representation of trees :: TreeG a b :== EITHER a (PAIR b (PAIR (Tree a b) (Tree a b))) • Generated instance for trees instance map***Treewhere map*** f1 f2 x = toTree (mapTreeG f1 f2 (fromTree x)) mapTreeG :: (a1b1) (a2b2) (TreeG a1 a2) TreeG b1 b2 mapTreeG f1 f2 = map*** f1 (map*** f2 (map*** (map*** f1 f2) (map*** f1 f2))) • After resolving overloading mapTreeG f1 f2 = mapEITHER f1 (mapPAIR f2 (mapPAIR (mapTree f1 f2) (mapTree f1 f2))) A Generic Programming Extension for Clean
Applying map • Overloaded fmap and bimap can be defined in terms of generic map fmap :: (a b) (t a) (t b) | map{|**|} t fmap f x = map{|**|} f x bimap :: (a b) (c d) (t a c) (t b d) | map{|***|} t bimap f g x = map{|***|} f g x • Kind index must be specified mapinc1 = map{|**|} inc mapinc2 = map{|***|} inc A Generic Programming Extension for Clean
Contents (3) • Introduction to Generic programming • Generics in Clean • Customized instances • Conclusion A Generic Programming Extension for Clean
Customized instances • Allow for mixing of • Generic behavior • Specific behavior • The user can specify an instance in terms of the generated instance A Generic Programming Extension for Clean
Collecting free variables :: Expr = Lambda Var Expr | App Expr Expr | … generic vars :: a [Var] instance vars UNIT where vars x = [] instance vars EITHER where vars vl vr (LEFT x) = vl x vars vl vr (RIGHT x) = vr x instance vars PAIR where vars vx vy (PAIR x y) = removeDup (vx x ++ vy y) instance vars Var where vars v = [v] instance vars Expr where vars (Lambda arg expr) = removeMember arg (vars{|*|} expr) vars x = vars{|generic|} x A Generic Programming Extension for Clean
Contents (4) • Introduction to Generic programming • Generics in Clean • Customized instances • Conclusion A Generic Programming Extension for Clean
Contributions • Kind-indexed classes • One generic function works for all kinds • Overloaded functions can be defined generically • Customized instances provide a way to combine • Generic behavior • Specific behavior A Generic Programming Extension for Clean
Future work • Optimization • Types of higher-order kinds • Constructor information • Uniqueness typing • Array types • Explicit recursion in the generic representation of types A Generic Programming Extension for Clean