## Generic Haskell: practice and theory (2003)

### Cached

### Download Links

- [www.cs.bonn.edu]
- [www.cs.uu.nl]
- [www.cs.uu.nl]
- [www.informatik.uni-bonn.de]
- DBLP

### Other Repositories/Bibliography

Venue: | In Generic Programming, Advanced Lectures, volume 2793 of LNCS |

Citations: | 69 - 23 self |

### BibTeX

@INPROCEEDINGS{Hinze03generichaskell:,

author = {Ralf Hinze and Johan Jeuring},

title = {Generic Haskell: practice and theory},

booktitle = {In Generic Programming, Advanced Lectures, volume 2793 of LNCS},

year = {2003},

pages = {1--56},

publisher = {Springer-Verlag}

}

### Years of Citing Articles

### OpenURL

### Abstract

Abstract. Generic Haskell is an extension of Haskell that supports the construction of generic programs. These lecture notes describe the basic constructs of Generic Haskell and highlight the underlying theory. Generic programming aims at making programming more effective by making it more general. Generic programs often embody non-traditional kinds of polymorphism. Generic Haskell is an extension of Haskell [38] that supports the construction of generic programs. Generic Haskell adds to Haskell the notion of structural polymorphism, the ability to define a function (or a type) by induction on the structure of types. Such a function is generic in the sense that it works not only for a specific type but for a whole class of types. Typical examples include equality, parsing and pretty printing, serialising, ordering, hashing, and so on. The lecture notes on Generic Haskell are organized into two parts. This first part motivates the need for genericity, describes the basic constructs of Generic Haskell, puts Generic Haskell into perspective, and highlights the underlying theory. The second part entitled “Generic Haskell: applications ” delves deeper into the language discussing three non-trivial applications of Generic Haskell: generic dictionaries, compressing XML documents, and a generic version of the zipper data type. The first part is organized as follows. Section 1 provides some background discussing type systems in general and the type system of Haskell in particular. Furthermore, it motivates the basic constructs of Generic Haskell. Section 2 takes a closer look at generic definitions and shows how to define some popular generic functions. Section 3 highlights the theory underlying Generic Haskell and discusses its implementation. Section 4 concludes. 1

### Citations

985 | A Theory of Type Polymorphism in Programming
- Milner
- 1978
(Show Context)
Citation Context ...ion that works for all data types is consequently a non-issue.) Polymorphic type systems Polymorphism complements type security by flexibility. Polymorphic type systems like the Hindley-Milner system =-=[20] a-=-llow the definition of functions that behave uniformly over all types. A standard example is the length function that computes the length of a list. data List a = Nil | Cons a (List a) length :: ∀a ... |

352 |
A compendium of continuous lattices
- Gierz, Hofmann, et al.
- 1980
(Show Context)
Citation Context ... (a2 → a1) → ∀b1 b2 . (b1 → b2) → ((a1 → b1) → (a2 → b2)) (f → g) h = g · h · f . In the case of mapping functions we can remedy the situation by drawing from the theory of embeddings and projections =-=[13]-=-. The central idea is to supply a pair of functions, from and to, where to is the left-inverse of from, that is, to · from = id. (If the functions additionally satisfy from · to ⊑ id, then they are ca... |

342 |
Foundations for programming languages
- Mitchell
- 1996
(Show Context)
Citation Context ...e simply typed lambda calculus. A basic knowledge of this material will prove useful for specializing type-indexed values. Most of the definitions are taken from the excellent textbook by J. Mitchell =-=[21]. Sy-=-ntax Syntactic categories The simply typed lambda calculus has a two-level structure (kinds and types—since we will use the calculus to model Haskell’s type system we continue to speak of kinds an... |

339 | Theorems for free
- Wadler
- 1989
(Show Context)
Citation Context ...s flexible that one would wish. For instance, it is not possible to define a polymorphic equality function that works for all types. eq :: ∀a . a → a → Bool -- does not work The parametricity th=-=eorem [28] impli-=-es that a function of type ∀a . a → a → Bool must necessarily be constant. As a consequence, the programmer is forced to program a separate equality function for each type from scratch. And this... |

299 |
Interprétation fonctionelle et élimination des coupures de l’arithmétique d’ordre supérieur
- Girard
- 1972
(Show Context)
Citation Context ... firstclass polymorphism. For instance, eqGRose takes a polymorphic argument to a polymorphic result. To make the use of polymorphism explicit we will use a variant of the polymorphic lambda calculus =-=[14]-=- (also known as F ω) both for defining and for specializing type-indexed values. This section provides a brief introduction to the calculus. As an aside, note that a similar language is also used as t... |

267 | Compiling polymorphism using intensional type analysis
- Harper, Morrisett
- 1995
(Show Context)
Citation Context ...ons using the so-called dictionary passing translation, which is quite similar to the implementation technique of Generic Haskell. Intensional type analysis The framework of intensional type analysis =-=[16]-=- was originally developed as a means to improve the implementation of polymorphic functions. It was heavily employed in typed intermediate languages not intended for programmers but for compiler write... |

243 | Purely Functional Data Structures
- Okasaki
- 1998
(Show Context)
Citation Context ...llowing generalization of rose trees, that abstracts over the List data type, illustrates this feature. data GRose f a = GBranch a (f (GRose f a)) A slight variant of this definition has been used by =-=[24] to extend an -=-implementation of priority queues with an efficient merge operation. The type constructor GRose has kind (∗ → ∗) → (∗ → ∗), that is, GRose has a so-called second-order kind where the ord... |

228 |
Introduction to Functional Programming using Haskell
- Bird
- 1998
(Show Context)
Citation Context ...ee has kind ⋆ → ⋆ → ⋆. Perhaps surprisingly, binary type constructors like Tree are curried in Haskell. The following data type declaration captures multiway branching trees, also known as rose trees =-=[6]-=-. data Rose a = Branch a (List (Rose a)) A node is labelled with an element of type a and has a list of subtrees. An example element of type Rose Int is: Branch 2 (Cons (Branch 3 Nil) (Cons (Branch 5 ... |

224 | Cayenne - a language with dependent types
- Augustsson
- 1998
(Show Context)
Citation Context ...s If a higher level depends on a lower level we have so-called dependent types or dependent kinds. Programming languages with dependent types are the subject of intensive research, see, for instance, =-=[4]-=-. Dependent types will play little rôle in these notes as generic programming is concerned with the opposite direction, .s18 R. Hinze, J. Jeuring where a lower level depends on the same or a higher le... |

141 | Type inference with polymorphic recursion
- Henglein
- 1993
(Show Context)
Citation Context ...morphic recursion only if an explicit type signature is provided for the function. The rationale behind this restriction is that type inference in the presence of polymorphic recursion is undecidable =-=[17]-=-. Though the Sequ data type is more complex than the list data type, encoding binary random-access lists is not any more difficult. encodeSequ encodeChar (ZeroS (ZeroS (OneS (Fork (Fork ’L’ ’i’) (Fork... |

108 | Polytypic values possess polykinded types
- Hinze
- 2002
(Show Context)
Citation Context ...Hint: consider the type ConDescr. Which information is useful for your task? 3 Generic Haskell—Theory This section highlights the theory underlying Generic Haskell (most of the material is taken fro=-=m [14]-=-). We have already indicated that Generic Haskell takes a transformational approach to generic programming: a generic function is translated into a family of polymorphic functions. We will see in this... |

98 |
Polymorphic type schemes and recursive definitions
- Mycroft
- 1984
(Show Context)
Citation Context ...eFork encodea). The type of the component determines the calls in a straightforward manner. As an aside, note that encodeSequ requires a non-schematic form of recursion known as polymorphic recursion =-=[23]. The -=-recursive calls are at type (Fork a → Bin) → (Sequ (Fork a) → Bin) which is a substitution instance of the declared type. Functions operating on nested types are in general polymorphically recur... |

97 | A new approach to generic functional programming - Hinze - 2000 |

96 | Bananas in Space: Extending Fold and Unfold to Exponential Types
- Meijer, Hutton
- 1995
(Show Context)
Citation Context ...order(l)}. Applying GRose to List yields the type of rose trees. The following data type declaration introduces a fixed point operator on the level of types. This definition appears, for instance, in =-=[19]-=- where it is employed to give a generic definition of so-called cata- and anamorphisms. newtype Fix f = In (f (Fix f )) data ListBase a b = NilL | ConsL a b The kinds of these type constructors are Fi... |

87 |
Polymorphic type inference
- Leivant
- 1983
(Show Context)
Citation Context ... . (∀a1 a2 . (a1 → a2) → (f1 a1 → f2 a2)) → (Fix f1 → Fix f2) mapFix mapf (In v) = In (mapf (mapFix mapf ) v), which takes a polymorphic function as argument. In other words, mapFix has a =-=rank-2 type [17]. Th-=-e argument function, mapf , has a more general type than one would probably expect: it takes a function of type a1 → a2 to a function of type f1 a1 → f2 a2. By contrast, the mapping function for L... |

84 | Nested datatypes
- Bird, Meertens
- 1998
(Show Context)
Citation Context ...e definition does not involve a change of the type parameter(s). The data types of the previous section are without exception regular types. This section is concerned with non-regular or nested types =-=[7]-=-. Nested data types are practically important since they can capture data-structural invariants in a way that regular data types cannot. For instance, the following data type declaration defines perfe... |

75 | A lightweight implementation of generics and dynamics
- Cheney, Hinze
- 2002
(Show Context)
Citation Context ...t necessarily ignore its second and its third argument. The trick is to use a parametric type for type representations: eq :: ∀a . Rep a → a → a → Bool. Here Rep t is the type representation of t. In =-=[9, 5]-=- it is shown how to define a Rep type in Haskell (augmented with existential types). This approach is, however, restricted to types of one fixed kind. Dependent types We have noted above that the type... |

59 | Compiling Haskell by program transformation: A report from the trenches. Pages 18–44 of: ESOP’96
- Jones, Simon
- 1996
(Show Context)
Citation Context ...alizing typeindexed values. This section provides a brief introduction to the calculus. As an aside, note that a similar language is also used as the internal language of the Glasgow Haskell Compiler =-=[26]-=-. Syntactic categories The polymorphic lambda calculus has a three-level structure (kinds, type schemes, and terms) incorporating the simply typed lambda calculus on the type level. type schemes R, S ... |

58 | Generic programming within dependently typed programming
- Altenkirch, McBride
- 2003
(Show Context)
Citation Context ... Haskell assigns to equality resembles a dependent type. Thus, it comes as little surprise that wesGeneric Haskell: practice and theory 21 can simulate Generic Haskell in a dependently typed language =-=[2]-=-. In such a language we can define a simple, non-parametric type Rep of type representations. The correspondence between a type and its representative is established by a function Type :: Rep → ⋆ that... |

41 | A generic programming extension for Haskell
- Hinze
- 1999
(Show Context)
Citation Context ...1 i−1 t) if n > 1 ∧ i > 1 ⎧ ⎨ Unit if n = 0 tuple t1 . . . tn = t1 if n = 1 ⎩ (t1 :*: tuple t2 . . . tn) if n > 1. An alternative encoding, which is based on a binary sub-division scheme, is given in =-=[18]-=-. Most generic functions are insensitive to the translation of sums and products. Two notable exceptions are encode and decodes, for which the binary sub-division scheme is preferable (the linear enco... |

41 | Calculate polytypically
- Meertens
- 1996
(Show Context)
Citation Context ...l ] → Bool all, any :: (a → Bool) → [a ] → Bool length :: [a ] → Int minimum, maximum :: (Ord a) ⇒ [a ] → a concat :: [[a ]] → [a ]. These are examples of so-called reductions. A reduc=-=tion or a crush [18]-=- is a function that collapses a structure of values of type x into a single value of type x. This section explains how to define reductions that work for all types of all kinds. To illustrate the main... |

36 | Generalised folds for nested datatypes
- Bird, Paterson
- 1999
(Show Context)
Citation Context ... the λ-dropped and the λ-lifted version correspond to two different methods of modelling parameterized types: families of first-order fixed points versus higher-order fixed points, see, for instance, =-=[8]-=-. Environment models This section is concerned with the denotational semantics of the simply typed lambda calculus. There are two general frameworks for describing the semantics: environment models an... |

33 |
Category Theoretic Approach to Data Types
- Hagino
- 1987
(Show Context)
Citation Context ... the phrase intensional polymorphism, and J. Jeuring invented the word polytypism [28]. The mainstream of generic programming is based on the initial algebra semantics of datatypes, see, for instance =-=[15]-=-, and puts emphasis on general recursion operators like mapping functions and catamorphisms (folds). In [43] several variations of these operators are informally defined and algorithms are given that ... |

23 | A category-theoretic account of program modules
- Moggi
- 1989
(Show Context)
Citation Context ...ndent product: the type of the last component depends on the first n components.s40 R. Hinze, J. Jeuring A similar structure has also been used to give a semantics to Standard ML’s module system, se=-=e [22]. Second,-=- if T is a closed type term, then P�∅ ⊢ T :: T�η is of the form ([T ], . . . , [T ]; [poly{|T |}]) where poly{|T |} is the desired instance. As an aside, note that this is in agreement with p... |

22 | Polytypic compact printing and parsing
- Jansson, Jeuring
- 1999
(Show Context)
Citation Context ... for each instance of the class. Towards generic data compression The first problem we look at is to encode elements of a given data type as bit streams implementing a simple form of data compression =-=[15]-=-. For concreteness, we assume that bit streams are given by the following data type: type Bin = [Bit ] data Bit = 0 | 1. Thus, a bit stream is simply a list of bits. A real implementation might have a... |

15 |
Doaitse Swierstra. Typing dynamic typing
- Baars, S
- 2002
(Show Context)
Citation Context ...t necessarily ignore its second and its third argument. The trick is to use a parametric type for type representations: eq :: ∀a . Rep a → a → a → Bool. Here Rep t is the type representation of t. In =-=[9, 5]-=- it is shown how to define a Rep type in Haskell (augmented with existential types). This approach is, however, restricted to types of one fixed kind. Dependent types We have noted above that the type... |

13 | An extensional characterization of lambda-lifting and lambda-dropping
- Danvy
- 1998
(Show Context)
Citation Context ...List a = Nil | Cons a (List a) Fix (ΛList . Λa . Unit :+: a :*: List a). Interestingly, the representation of regular types such as List can be improved by applying a technique called lambda-dropping =-=[11]-=-: if Fix (Λf . Λa . t) is regular, then it is equivalent to Λa . Fix (Λb . t[f a := b]) where t[t1 := t2 ] denotes the type term, in which all occurrences of t1 are replaced by t2. For instance, the λ... |

10 |
Functional Pearl: Perfect trees and bit-reversal permutations
- Hinze
(Show Context)
Citation Context ...g important since they can capture data-structural invariants in a way that regular data types cannot. The following data type declaration, for instance, defines perfectly balanced, binary leaf trees =-=[12]��-=-�perfect trees for short. data Perfect a = ZeroP a | SuccP (Perfect (Fork a)) This equation can be seen as a bottom-up definition of perfect trees: a perfect tree is either a singleton tree or a perfe... |

5 |
Available from http://www.haskell.org/hugs
- Jones, Peterson
- 1999
(Show Context)
Citation Context ...morphism. Haskell—or rather, extensions of Haskell come quite close to this ideal language. The Glasgow Haskell Compiler, GHC, [27], the Haskell B. Compiler, HBC, [1] and the Haskell interpreter Hug=-=s [16]-=- provide rank-2 type signatures. The latest version of GHC, 5.04, even supports general rank-n types. There is, however, one fundamental difference between Haskell and (our presentation) of the polymo... |

3 |
Polytypic programming with ease (extended abstract
- Hinze
- 1999
(Show Context)
Citation Context ...g generic functions. The generic definitions are similar to ours (modulo notation) except that the generic programmer must additionally consider cases for type composition and for type recursion (see =-=[19]-=- for a more detailed comparison). Most approaches are restricted to first-order kinded, regular datatypes (or even subsets of this class). One notable exception is the work of F. Ruehr [42], who prese... |

2 |
Recursive subtyping revealed (functional pearl
- Gapeyev, Levin, et al.
- 2000
(Show Context)
Citation Context ...n E. The equational proof rules identify a recursive type Fixκ t and its unfolding t (Fixκ t). In general, there are two flavours of recursive types: equi-recursive types and iso-recursive types, see =-=[12]-=-. In the latter system Fixκ t and t (Fixκ t) must only be isomorphic rather than equal. The subsequent development is largely independent of this design choice. We use equi-recursive types because the... |

1 |
The Haskell B
- Augustsson
- 1998
(Show Context)
Citation Context ... as an equality rather than as an isomorphism. Haskell—or rather, extensions of Haskell come quite close to this ideal language. The Glasgow Haskell Compiler, GHC, [45], the Haskell B. Compiler, HBC, =-=[3]-=- and the Haskell interpreter Hugs [29] provide rank-2 type signatures. The latest version of the Glasgow Haskell Compiler, GHC 5.04, even supports general rank-n types. There is, however, one fundamen... |

1 |
The HBC compiler
- Augustsson
- 1998
(Show Context)
Citation Context ... as an equality rather than as an isomorphism. Haskell—or rather, extensions of Haskell come quite close to this ideal language. The Glasgow Haskell Compiler, GHC, [27], the Haskell B. Compiler, HBC=-=, [1]-=- and the Haskell interpreter Hugs [16] provide rank-2 type signatures. The latest version of GHC, 5.04, even supports general rank-n types. There is, however, one fundamental difference between Haskel... |