Structured Recursion for Non-Uniform Data-Types
Total Page:16
File Type:pdf, Size:1020Kb
Structured recursion for non-uniform data-types by Paul Alexander Blampied, B.Sc. Thesis submitted to the University of Nottingham for the degree of Doctor of Philosophy, March 2000 Contents Acknowledgements .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 1 Chapter 1. Introduction .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 2 1.1. Non-uniform data-types .. .. .. .. .. .. .. .. .. .. .. .. 3 1.2. Program calculation .. .. .. .. .. .. .. .. .. .. .. .. .. 10 1.3. Maps and folds in Squiggol .. .. .. .. .. .. .. .. .. .. .. 11 1.4. Related work .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 14 1.5. Purpose and contributions of this thesis .. .. .. .. .. .. .. 15 Chapter 2. Categorical data-types .. .. .. .. .. .. .. .. .. .. .. .. 18 2.1. Notation .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 19 2.2. Data-types as initial algebras .. .. .. .. .. .. .. .. .. .. 21 2.3. Parameterized data-types .. .. .. .. .. .. .. .. .. .. .. 29 2.4. Calculation properties of catamorphisms .. .. .. .. .. .. .. 33 2.5. Existence of initial algebras .. .. .. .. .. .. .. .. .. .. .. 37 2.6. Algebraic data-types in functional programming .. .. .. .. 57 2.7. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 61 Chapter 3. Folding in functor categories .. .. .. .. .. .. .. .. .. .. 62 3.1. Natural transformations and functor categories .. .. .. .. .. 63 3.2. Initial algebras in functor categories .. .. .. .. .. .. .. .. 68 3.3. Examples and non-examples .. .. .. .. .. .. .. .. .. .. 77 3.4. Existence of initial algebras in functor categories .. .. .. .. 82 3.5. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 105 Chapter 4. Folding with algebra families .. .. .. .. .. .. .. .. .. .. 107 4.1. Overview of the process .. .. .. .. .. .. .. .. .. .. .. .. 107 4.2. Identifying the possible constructor instances .. .. .. .. .. 109 4.3. Algebra families .. .. .. .. .. .. .. .. .. .. .. .. .. .. 113 4.4. Algebra family folds .. .. .. .. .. .. .. .. .. .. .. .. .. 120 4.5. Constructing algebra families for nests .. .. .. .. .. .. .. 122 4.6. Deriving algebra families and folds for other non-uniform data- types .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 128 4.7. Examples .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 132 4.8. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 137 Chapter 5. Categorical semantics for algebra family folds .. .. .. .. .. 139 5.1. Set-indexed families of objects and arrows .. .. .. .. .. .. 140 5.2. Finding the indexing set .. .. .. .. .. .. .. .. .. .. .. .. 142 5.3. Next functors .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 142 5.4. Initial algebra families and catamorphisms .. .. .. .. .. .. 147 5.5. Comparison with functor category catamorphisms .. .. .. .. 152 5.6. Transformation laws for algebra family folds .. .. .. .. .. 153 5.7. Existence of initial algebra families .. .. .. .. .. .. .. .. 162 5.8. Initial algebra families in Haskell .. .. .. .. .. .. .. .. .. 168 5.9. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 169 iii Chapter 6. Mapping over non-uniform data-types .. .. .. .. .. .. .. 171 6.1. Mapping using algebra family folds .. .. .. .. .. .. .. .. 173 6.2. Proving properties of maps .. .. .. .. .. .. .. .. .. .. .. 178 6.3. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 181 Chapter 7. Conclusion .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 182 7.1. Summary .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 182 7.2. Discussion .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 183 7.3. Future work .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 185 Appendix A. Long proofs .. .. .. .. .. .. .. .. .. .. .. .. .. .. 189 A.1. Regular types in functor categories .. .. .. .. .. .. .. .. 189 A.2. Lifting functors .. .. .. .. .. .. .. .. .. .. .. .. .. .. 194 A.3. Order-enriched categories .. .. .. .. .. .. .. .. .. .. .. 201 A.4. Order-enriching functor categories .. .. .. .. .. .. .. .. 203 A.5. Order-enriching algebra families .. .. .. .. .. .. .. .. .. 213 Appendix B. Basic category theory .. .. .. .. .. .. .. .. .. .. .. .. 221 References .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 228 iv Abstract Recursion is a simple but powerful programming technique used extensively in functional languages. For a number of reasons, however, it is often desirable to use structured forms of recursion in programming, encapsulated in so-called recursion operators, in preference to unrestricted recursion. In particular, using recursion op- erators has proved invaluable for transforming and reasoning about functional pro- grams. The recursion operators map and fold are well-understood for uniform data- types, and recent work on applications of non-uniform data-types has motivated extending these recursion operators to non-uniform data-types as well. Previous work on defining recursion operators for non-uniform data-types has been hampered by expressibility problems caused by parametric polymorphism. In this thesis, we show how these problems can be solved by taking a new approach, based upon the idea of “algebra families”. We show how these recursion operators can be realized in the functional language Haskell, and present a categorical seman- tics that supports formal reasoning about programs on non-uniform data-types. vi Acknowledgements I would like firstly to thank my supervisors, Graham Hutton and Mark Jones, for steering me in the right direction and for always making the time to help me. My gratitude goes to my colleagues in Lapland for putting up with my incessant ignorant questions: Tony Daniels, Ben Gaster, Claus Reinke, Colin Taylor and Richard Verhoeven, and all the other members, past and present, of the Languages and Programming group. Special thanks to my family for supporting and encouraging me, and my friends for making my time in Nottingham much more than just an academic experience. Finally, I would like to thank the States of Jersey Education Committee for support- ing my research with a three-year grant, without which this thesis would not have been possible. 1 Chapter 1. Introduction Data-types in programming languages allow us to organize values according to their propertiesand purpose. Basic data-types include integers,floating-point num- bers, booleans, characters, strings, and so on. Most languages provide ways to con- struct more complex types such as arrays, lists and trees. The ability to express and use complex data-structures in a flexible and straightforward way is an important measure of the usability and expressiveness of a programming language. Modern functional languages excel at this, and their type systems are being continually developed to bring greater expressiveness and control to the programmer. In this thesis we concentrate on a class of data-types called non-uniform or nested [BirdM98] data-types that can be defined in the powerful polymorphic type systems of modern functional languages such as Haskell [PeytonJonesH99] and ML [MilnerTHM97], but have received little attention because the same type systems prevent the pro- grammer from defining practically useful functions over them. Haskell and ML have type systems based on the Hindley–Milner type system [Milner78]. This system allows all functions to be statically typed at compile-time, thus ensuring that no run-time type errors can occur. It allows the definition of recursive types which can describe data-structures of varying size. The most common example of a recursive data-type is that of lists, which are ubiquitous in functional programming. In contrast to uniform recursive types such as lists and binary trees where the structure remains the same at different recursion levels, non-uniform or nested data- types have structures that change with recursion depth. The changing structure in these data-types makes it difficult or impossible to define useful functions over them using the Hindley–Milner type system, but some recent extensions to the 2 1.1. Non-uniform data-types 3 Haskell type system, namely polymorphic recursion [Mycroft84]and rank-2 type signa- tures [McCracken84, PeytonJones], have removed many of the technical barriers and such definitions are now feasible. Researchers have begun to explore applications of non-uniform data-types. The most promising of these is that non-uniform data-types can be used to encode certain structural invariants on uniform data-types, which can then be checked and enforced automatically by the type system. Because of the extra structural complexity inherent in non-uniform types, re- cursive functions on non-uniform data-types are more difficult to design than simi- lar functions on uniform types. This thesis advocates the use of recursion operators to impose a structure on such function definitions and hide the complexities from the programmer. In particular, we transfer and generalize the recursion operators map and fold to operate on non-uniform data-types. These provide “prepackaged” recursion for a particular type, and are general enough to be suitable for many com- mon operations. Map and fold are central to the Squiggol [Bird87, Malcolm90, BirddM97] style of transformational programming for functional languages, and, for uniform types, have an elegant and well-understood semantics in category theory [Hagino87, Mal- colm90, FokkingaM91]. As we transfer the map and fold operators to non-uniform data-types, we develop an appropriate categorical semantics that will allow us to prove certain properties and laws about them following in the spirit of Squiggol. The following sections describe in more detail the class of non-uniform data- types we are considering and