https://wiki.haskell.org/api.php?action=feedcontributions&user=Tschrijvers&feedformat=atomHaskellWiki - User contributions [en]2024-03-19T12:40:12ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Books&diff=66505Books2024-02-02T12:53:11Z<p>Tschrijvers: /* Textbooks */</p>
<hr />
<div>Books covering many aspects of Haskell.<br />
<br />
In addition to this wiki page, many English books related to Haskell are listed in a <br />
[https://www.extrema.is/articles/haskell-books "Haskell Books index"]. An<br />
[https://www.extrema.is/articles/tag/index:haskell-books.rss "RSS feed"]<br />
can be used to receive notifications when new books are added to the index.<br />
<br />
==Language and library definition==<br />
<br />
<DL><br />
<br />
<DT>[[Image:Haskell_98_Language_and_Libraries.jpg|frameless|right|Cover]]<br />
Simon Peyton Jones: [https://www.haskell.org/definition/haskell98-report.pdf "Haskell 98 language and libraries: the Revised Report"], Cambridge University Press, 2003, Hardback, 272 pages, ISBN 0521826144, £45.00<br />
<DD><br />
<B>Book Description</B><BR> <br />
Haskell is the world's leading lazy functional programming language,<br />
widely used for teaching, research, and applications. The language<br />
continues to develop rapidly, but in 1998 the community decided to<br />
capture a stable snapshot of the language: Haskell 98. All Haskell<br />
compilers support Haskell 98, so practitioners and educators alike<br />
have a stable base for their work. This book constitutes the agreed<br />
definition of the Haskell 98, both the language itself and its<br />
supporting libraries. It has been considerably revised and refined<br />
since the original definition, and appears in print for the first<br />
time. It should be a standard reference work for anyone involved in<br />
research, teaching, or application of Haskell.<br />
<br />
The entire language definition is also available online:<br />
[[Language_and_library_specification|Language and library<br />
specification]].<br />
</DL><br />
<br />
==Textbooks==<br />
<br />
<DL><br />
<dt>Tom Schrijvers : <br />
[[Image: Soar with Haskell cover.jpg|frameless|right|70px|Cover]] [https://www.packtpub.com/product/soar-with-haskell/9781805128458 Soar with Haskell], ISBN13 9781805128458, Paperback/eBook: 418 pages. Packt (December 2023). <br />
<dd><br />
<B>Book Description</B><BR><br />
With software systems reaching new levels of complexity and programmers aiming for the highest productivity levels, software developers and language designers are turning toward functional programming because of its powerful and mature abstraction mechanisms. This book will help you tap into this approach with Haskell, the programming language that has been leading the way in pure functional programming for over three decades. The book begins by helping you get to grips with basic functions and algebraic datatypes, and gradually adds abstraction mechanisms and other powerful language features. Next, you’ll explore recursion, formulate higher-order functions as reusable templates, and get the job done with laziness. As you advance, you’ll learn how Haskell reconciles its purity with the practical need for side effects and comes out stronger with a rich hierarchy of abstractions, such as functors, applicative functors, and monads. Finally, you’ll understand how all these elements are combined in the design and implementation of custom domain-specific languages for tackling practical problems such as parsing, as well as the revolutionary functional technique of property-based testing. By the end of this book, you’ll have mastered the key concepts of functional programming and be able to develop idiomatic Haskell solutions.<br />
<br />
<dt>John Whitington : [[Image: Hftvb-cover.jpg|frameless|right|70px|Cover]] [https://haskellfromtheverybeginning.com/ Haskell from the Very Beginning], ISBN13 9780957671133, Paperback/eBook: 216 pages. Coherent Press (October 2019)<br />
<dd><br />
<B>Book Description</B><BR><br />
In Haskell from the Very Beginning John Whitington takes a no-prerequisites approach to teaching the basics of a modern general-purpose programming language. Each small, self-contained chapter introduces a new topic, building until the reader can write quite substantial programs. There are plenty of questions and, crucially, worked answers and hints.<br />
<br />
Haskell from the Very Beginning will appeal both to new programmers, and to experienced programmers eager to explore functional languages such as Haskell. It is suitable both for formal use within an undergraduate or graduate curriculum, and for the interested amateur.<br />
<br />
<dt>Alexander Granin : [[Image: fdaa-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/functional-design-and-architecture Functional Design and Architecture, Second Edition], ISBN13 9781617299612, Paperback/eBook: 575 pages (estimated). Manning Publications (Fall December 2021)<br />
<dd><br />
<B>Book Description</B><BR><br />
Functional Design and Architecture is a practical book that covers the biggest gap in the Haskell ecosystem: how to design real-world applications with low complexity and low risks. Application architectures, design patterns, best practices, methodologies and approaches - everything you need to write a high-quality code. The book introduces a new methodology - Functional Declarative Design, - and provides a comprehensive, complete view of Software Engineering in Haskell. It covers all the main topics: requirements analysis, domain-driven design, testing, domain-specific languages, databases, logging, multithreading, type-level programming, and so on.<br />
<br />
This book doesn't introduce you to the Haskell language, but instead, it tells about high-level topics of Software Design. It can be your third Haskell book.<br />
<br />
This is the second edition of the book.<br />
<br />
<dt>Vitaly Bragilevsky : [[Image: Hid-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/haskell-in-depth Haskell in Depth], ISBN13 9781617295409, Paperback/eBook: 664 pages. Manning Publications (May 2021)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell in Depth is the perfect second book on Haskell. After a quick refresher on Haskell basics, this hands-on guide dives into examples and application scenarios designed to teach how Haskell works and how to apply it correctly. You’ll learn about managing projects with Cabal and Stack, tackle error-handling and testing, and package programs and libraries for production deployment.<br />
<br />
You’ll appreciate coverage of advanced Haskell features including programming polymorphically, working effectively with types, concurrent programming, data processing, web services, and more. Because it’s organized to make specific topics easy to find, you’ll return to this book again and again as your go-to Haskell reference.<br />
<br />
<dt>Will Kurt : [[Image: Gph-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/get-programming-with-haskell Get Programming with Haskell], ISBN13 9781617293764, Paperback/eBook: 616 pages. Manning Publications (March 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Get Programming with Haskell leads you through short lessons, examples, and exercises designed to make Haskell your own. It has crystal-clear illustrations and guided practice. You will write and test dozens of interesting programs and dive into custom Haskell modules. You will gain a new perspective on programming plus the practical ability to use Haskell in the everyday world. (The 80 IQ points: not guaranteed!)<br />
<br />
<dt>[[Image:beginning_haskell.jpg|frameless|right|70px|Cover]] Alejandro Serrano Mena: [http://www.apress.com/9781430262503 <em>Beginning Haskell</em>], Paperback / eBook: 498 pages, Apress (January 2014), English, ISBN: 978-1-43026-250-3<br />
<dd><B>Book Description</B><BR><br />
Beginning Haskell provides a broad-based introduction to the Haskell language, its libraries and environment, and to the functional programming paradigm that is fast growing in importance in the software industry. The book takes a project-based approach to learning the language that is unified around the building of a web-based storefront. Excellent coverage is given to the Haskell ecosystem and supporting tools. These include the Cabal build tool for managing projects and modules, the HUnit and QuickCheck tools for software testing, the Scotty framework for developing web applications, Persistent and Esqueleto for database access, and also parallel and distributed programming libraries.<br />
<br />
<dt>[[Image:Lyah.png|frameless|right|70px|Cover]] Miran Lipovača: [http://www.nostarch.com/lyah.htm <em>Learn You a Haskell for Great Good!</em>], Paperback: 360 pages, No Starch Press (April 2011), English, ISBN: 978-1-59327-283-8<br />
<dd><B>Book Description</B><BR><br />
It's all in the name: Learn You a Haskell for Great Good! is a hilarious, illustrated guide to this complex functional language. Packed with the author's original artwork, pop culture references, and most importantly, useful example code, this book teaches functional fundamentals in a way you never thought possible.<br />
<br />
<dt>[[Image:LearnPhysicsWithFunctionalProgramming_front.webp|frameless|right|70px|Cover]] Scott N. Walck: [https://lpfp.io <em>Learn Physics with Functional Programming: A Hands-on Guide to Exploring Physics with Haskell</em>], Paperback: 648 pages, No Starch Press (January 2023), English, ISBN: 978-1-7185-0166-9<br />
<dd><B>Book Description</B><BR><br />
This book shows how to encode basic theoretical physics in Haskell. The author currently uses it in a computational physics course for physics majors at Lebanon Valley College. It covers Newtonian mechanics, a little special relativity, and electromagnetic theory up to the Maxwell equations. The book<br />
teaches Haskell to people interested in science generally, or physics specifically.<br />
<br />
<dt>[[Image:pih.jpg|frameless|right|70px|Cover]] Graham Hutton: [http://www.cs.nott.ac.uk/~pszgmh/pih.html <em>Programming in Haskell</em>], Paperback: 318 pages, 120 exercises, Cambridge University Press (September 1, 2016), English, ISBN-13: 978-1316626221<br />
<dd><br />
<B>Book Description</B><BR> <br />
This new edition has been extensively updated and expanded to include recent and more advanced features of Haskell, new examples and exercises, selected solutions, and freely downloadable lecture slides and example code. The presentation is clean and simple, while also being fully compliant with the latest version of the language, including recent changes concerning applicative, monadic, foldable and traversable types.<br />
<br />
<dt>[[Image:Rwh-thumb.png|frameless|right|Cover]] Bryan O'Sullivan, Don Stewart, and John Goerzen: [http://book.realworldhaskell.org/ <em>Real World Haskell</em>], Paperback: 700 pages, O'Reilly, November 2008, English, ISBN-10: 0596514980, ISBN-13: 978-0596514983<br />
<dd><br />
See ''[[Real World Haskell]]''. <br />
<br />
<br><br />
<dt>[[Image:pcph-thumb.gif|70px|frameless|right|Cover]] Simon Marlow: [https://simonmar.github.io/pages/pcph.html <em>Parallel and Concurrent Programming in Haskell</em>], Paperback: 322 pages, O'Reilly, August 2013, English, ISBN-10: 1449335942, ISBN-13: 978-1449335946<br />
<dd><br />
<B>Book Description</B><BR> <br />
If you have a working knowledge of Haskell, this hands-on book shows you how to use the language’s many APIs and frameworks for writing both parallel and concurrent programs. You’ll learn how parallelism exploits multicore processors to speed up computation-heavy programs, and how concurrency enables you to write programs with threads for multiple interactions.<br />
<br />
Author Simon Marlow walks you through the process with lots of code examples that you can run, experiment with, and extend. Divided into separate sections on Parallel and Concurrent Haskell, this book also includes exercises to help you become familiar with the concepts presented:<br />
<br />
* Express parallelism in Haskell with the Eval monad and Evaluation Strategies<br />
* Parallelize ordinary Haskell code with the Par monad<br />
* Build parallel array-based computations, using the Repa library<br />
* Use the Accelerate library to run computations directly on the GPU<br />
* Work with basic interfaces for writing concurrent code<br />
* Build trees of threads for larger and more complex programs<br />
* Learn how to build high-speed concurrent network servers<br />
* Write distributed programs that run on multiple machines in a network <br />
<br />
<br />
<DT>[[Image:The_Haskell_School_of_Expression.jpg|frameless|right|Cover]] Paul Hudak: [http://web.archive.org/web/20190705205338/https://www.cs.yale.edu/homes/hudak/SOE/ <EM>The Haskell School of Expression: Learning Functional Programming through Multimedia</EM>], Cambridge University Press, New York, 2000, 416pp, 15 line diagrams, 75 exercises, Paperback $29.95, ISBN 0521644089, Hardback $74.95, ISBN 0521643384<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book teaches functional programming as a way of thinking and<br />
problem solving, using Haskell, the most popular purely functional<br />
language. Rather than using the conventional mathematical examples<br />
commonly found in other programming language textbooks, the author<br />
draws examples from multimedia applications, including graphics,<br />
animation, and computer music, thus rewarding the reader with working<br />
programs for inherently more interesting applications. Aimed at both<br />
beginning and advanced programmers, this tutorial begins with a gentle<br />
introduction to functional programming and moves rapidly on to more<br />
advanced topics. An underlying theme is the design and implementation<br />
of <em>domain specific languages</em>, using three examples: FAL (a Functional<br />
Animation Language), IRL (an Imperative Robot Language), and MDL (a<br />
Music Description Language). Details about programming in Haskell<br />
are presented in boxes throughout the text so they can be easily<br />
referred to and found quickly.<br />
<br />
The book's [http://web.archive.org/web/20110720122354/http://plucky.cs.yale.edu/soe/ website] contains source files for all programs in the text, as well as the graphics libraries to run them under Windows and Linux platforms. It also contains PowerPoint slides useful for<br />
teaching a course using the textbook.<br />
<br />
*There is a review of SOE on this wiki: [[The Monad.Reader/Issue3/SoE Review]].<br />
<br />
<DT>[[Image:The_Craft_of_Functional_Programming.jpg|frameless|right|Cover]] Simon Thompson: [http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/ <EM>Haskell: The Craft of Functional Programming</EM>], Second Edition, Addison-Wesley, 507&nbsp;pages, paperback, 1999. ISBN 0-201-34275-8.<br />
<dd><br />
<B>Book Description</B><BR> <br />
The second edition of Haskell: The Craft of Functional Programming is essential reading for beginners to functional programming and newcomers to the Haskell programming language. The emphasis is on the process of crafting programs and the text contains many examples and running case studies, as well as advice an program design, testing, problem solving and how to avoid common pitfalls. <br />
<br />
Building on the strengths of the first edition, the book includes many new and improved features: <br />
*Complete coverage of Haskell 98, the standard version of Haskell which will be stable and supported by implementations for years to come. <br />
*An emphasis on software engineering principles, encouraging a disciplined approach to building reusable libraries of software components. <br />
*Detailed coverage of the Hugs interpreter with an appendix covering other implementations. <br />
*A running case study of pictures emphasizes the built-in functions which appear in the standard prelude and libraries. It is also used to give an early preview of some of the more complex language features, such as high-order functions. <br />
*List comprehensions and the standard functions over lists are covered before recursion. <br />
*Early coverage of polymorphism supporting the "toolkit" approach and encouraging the resuse of built-in functions and types. <br />
*Extensive reference material containing details of further reading in books, journals and on the World Wide Web. <br />
*Accompanying Web Site supporting the book, containing all the program code, further teaching materials and other useful resources. <br />
<B>Synopsis</B><BR> <br />
This books introduces Haskell at a level appropriate for those with little or no prior experience of functional programming. The emphasis is on the process of crafting programs, solving problems, and avoiding common errors.<br />
<br />
<DT>[[Image:Bird_TFWH.jpg|frameless|right|70 px|Cover]] Richard Bird: [https://www.cambridge.org/core/books/thinking-functionally-with-haskell/79F91D976F0C7229082325B41824EBBC# <EM>Thinking Functionally with Haskell</EM>], Cambridge University Press, 2014, 354 pp., ISBN-10: 1107452643, ISBN-13: 978-1107452640.<br />
<dd><br />
Richard Bird is famed for the clarity and rigour of his writing. His new textbook, which introduces functional programming to students, emphasises fundamental techniques for reasoning mathematically about functional programs. By studying the underlying equational laws, the book enables students to apply calculational reasoning to their programs, both to understand their properties and to make them more efficient. The book has been designed to fit a first- or second-year undergraduate course and is a thorough overhaul and replacement of his earlier textbooks. It features case studies in Sudoku and pretty-printing, and over 100 carefully selected exercises with solutions.<br />
<br />
<DT>[[Image:Introduction_to_Functional_Programming_Systems_Using_Haskell.jpg|frameless|right|Cover]] Antony Davie: <EM>[https://www.amazon.com/Introduction-Programming-INTRODUCTION-PROGRAMMING-Jun-18-1992/dp/B003Q5UPH4 An Introduction to Functional Programming Systems Using Haskell]</EM> Cambridge University Press, 1992. ISBN 0-521-25830-8 (hardback). ISBN 0-521-27724-8 (paperback).<br />
<dd>Cover:<br />
<br />
Functional programming is a style of programming that has become increasingly popular during the past few years.<br />
Applicative programs have the advantage of being almost immediately expressible as functional descriptions; they can<br />
be proved correct and transformed through the referential transparency property.<br />
<br />
This book presents the basic concepts of functional programming, using the language Haskell for examples. The author<br />
incorporates a discussion of lambda calculus and its relationship with Haskell, exploring the implications for<br />
raparallelism. Contents: SASL for Beginners / Examples of SASL Programming / More Advanced Applicative Programming<br />
Techniques / Lambda Calculus / The Relationship Between Lambda Calculus and SASL / Program Transformation and<br />
Efficiency / Correctness, Equivalence and Program Verification / Landin's SECD Machine and Related<br />
Implementations / Further Implementation Techniques / Special Purpose Hardware / The Applicative Style of<br />
Semantics / Other Applicative Languages / Implications for Parallelism / Functional Programming in Von Neumann<br />
Languages <br />
<br />
<DT>[[Image:Algorithms_A_Functional_Approach.jpg|frameless|right|Cover]] Fethi Rabhi and Guy Lapalme: [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html <EM> Algorithms: A functional programming approach</EM>], <br />
Addison-Wesley, 235&nbsp;pages, paperback, 1999. ISBN 0-201-59604-0<BR><br />
<DD><br />
<B>Book Description</B><BR> <br />
The authors challenge more traditional methods of teaching algorithms<br />
by using a functional programming context, with Haskell as an<br />
implementation language. This leads to smaller, clearer and more<br />
elegant programs which enable the programmer to understand the<br />
algorithm more quickly and to use that understanding to explore<br />
alternative solutions. <br><br />
<b>Key features:</b><br />
*Most chapters are self-contained and can be taught independently from each other.<br />
*All programs are in Haskell'98 and provided on a WWW site.<br />
*End of chapter exercises throughout.<br />
*Comprehensive index and bibliographical notes.<br />
<B>Synopsis</B><BR> <br />
The book is organised as a classic algorithms book according to topics<br />
such as Abstract Data Types, sorting and searching. It uses a<br />
succession of practical programming examples to develop in the reader<br />
problem-solving skills which can be easily transferred to other<br />
language paradigms. It also introduces the idea of capturing<br />
algorithmic design strategies (e.g. Divide-and-Conquer, Dynamic<br />
Programming) through higher-order functions.<br><br />
<b>Target audience</b><br><br />
The book is intended for computer science students taking algorithms<br />
and/or (basic or advanced) functional programming courses.<br />
<br />
<dt>[[Image:Fun_of_Programming.jpg|frameless|right|Cover]] Jeremy Gibbons and Oege de Moor (eds.): <em>[https://www.amazon.com/Fun-Programming-Cornerstones-Computing/dp/0333992857 The Fun of Programming]</em>,Palgrave, 2002, 288 pages. ISBN 0333992857.<br />
<dd><br />
<b>Book description:</b><br><br />
In this textbook, leading researchers give tutorial expositions on the current state of the art of functional<br />
programming. The text is suitable for an undergraduate course immediately following an introduction to<br />
functional programming, and also for self-study. All new concepts are illustrated by plentiful examples,<br />
as well as exercises. A [http://web.comlab.ox.ac.uk/oucl/publications/books/fop/ website] gives access to accompanying software.<br />
<br />
<dt>Simon Peyton Jones: [https://simon.peytonjones.org/publications-1980/#the-implementation-of-functional-programming-languages <em>Implementation of Functional Programming Languages</em>], 500 pages, Prentice-Hall, 1987. ISBN 0134533259.<br />
<dd><br />
This 1987 book is now out of print, but it is now available [https://www.microsoft.com/en-us/research/uploads/prod/1987/01/slpj-book-1987-r90.pdf online] in its entirety.<br />
<br />
<dt>Simon Peyton Jones, David Lester: [http://www.amazon.com/Implementing-Functional-Languages-Prentice-Hall-International/dp/0137219520/sr=1-1/qid=1162002704/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Implementing Functional Languages</em>], Paperback: 288 pages, Prentice Hall (August 1992), English, ISBN 0137219520 <br><br />
<dd><br />
The book is out of print. The full sources and a PDF version are <br />
[https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.109.8027&rep=rep1&type=pdf available for free].<br />
<br />
This book gives a practical approach to understanding the<br />
implementations of non-strict functional languages using lazy graph<br />
reduction. The emphasis of the book is on building working prototypes of<br />
several functional language implementations (template- instantiation,<br />
G-Machine, TIM, parallel G-Machine. In each case the authors provide a<br />
complete working prototype of a particular implementation, and then lead<br />
the reader through a sequence of improvements which expand its scope.<br />
This enables readers to develop, modify and experiment with their own<br />
implementations and for use as a source of practical laboratory work<br />
material.<br />
<br />
<dt>[[Image:TTFP.jpg|frameless|right|Cover]] Simon Thompson: [http://www.amazon.com/Functional-Programming-International-Computer-Science/dp/0201416670/sr=1-1/qid=1162002856/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Type Theory and Functional Programming</em>], Addison-Wesley, 1991. ISBN 0-201-41667-0. Hardcover: 388 pages.<br />
<dd><br />
Now out of print, the original version is available [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ here].<br />
<br />
<em>Preface</em>:<br />
Constructive Type theory has been a topic of research interest to computer scientists,<br />
mathematicians, logicians and philosophers for a number of years. For computer scientists it provides<br />
a framework which brings together logic and programming languages in a most elegant and fertile way:<br />
program development and verification can proceed within a single system. Viewed in a different way,<br />
type theory is a functional programming language with some novel features, such as the totality of<br />
all its functions, its expressive type system allowing functions whose result type depends upon the<br />
value of its input, and sophisticated modules and abstract types whose interfaces can contain logical<br />
assertions as well as signature information. A third point of view emphasizes that programs (or<br />
functions) can be extracted from proofs in the logic.<br />
<br />
<DT>[[Image:Uma_Abordagem_Pratica.jpg|frameless|right|Cover]] Claudio Cesar de Sá and Marcio Ferreira da Silva: <em> Haskell: Uma Abordagem Prática</em>, [http://www.novatec.com.br Novatec Editora Ltda.], 2006, 296 pages, ISBN 85-7522-095-0. The price is R$ 62,00 (in Reais). Language: Portuguese<br />
<dd><br />
This book is being published by Novatec Editora Ltda. You can access directly [http://www.novateceditora.com.br/livros/haskell/ here].<br />
<br><br />
<b>Book description:</b><br><br />
This book brings a comprehensive vision of Haskell language. No <br />
knowledge in another functional programming language is expected. In <br />
addition, no background in programming is required. The book presents <br />
issues from basic up to an intermediate level; it also includes some <br />
advanced aspects of Haskell. The title of the book, <em>Haskell: Uma <br />
Abordagem Prática</em>, in English <em>Haskell: A Practical Approach</em>, is the essence of the book. The result is a text that can be used in courses of programming and paradigms languages. Finally, many practical examples can be found throughout the book.<br />
<br />
An additional page containing comments on this book is found here:<br />
[http://web.archive.org/web/20170702235455/www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell http://www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell].<br />
Other data as bibtex entry, cover's book in several formats, Winhugs-2001 for download, and so on. This page is Portuguese.<br />
<br />
<dt>[[Image:portada.jpg|frameless|right|Cover]] Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo. [http://www.lcc.uma.es/~pepeg/pfHaskell/index.html <em>Razonando con Haskell</em>], Thompson 2004. ISBN 84-9732-277-0. Language: Spanish<br />
<dd><br />
Descripción El objetivo principal de este libro es el de servir como<br />
libro de texto de las asignaturas de Programación Declarativa<br />
correspondientes a los estudios de Informática o Ciencias de la<br />
Computación, y otras ciencias en general ( Matemáticas, Física, etc.).<br />
El texto es fruto de una larga experiencia docente de los autores dentro<br />
de las distintas asignaturas que desarrollan la Programación Funcional<br />
en distintas titulaciones de la Universidad de Málaga. Aún así, su<br />
lectura no queda condicionada a un conocimiento previo sobre lenguajes<br />
de programación (de computadores), ni sobre Informática. De esta forma,<br />
el libro puede ser utilizado por todo aquel que desee tener un<br />
conocimiento amplio sobre la Programación Funcional. <br />
<br />
<dt>[[Image:haskell-jp.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4839919623 Haskell Primer: The first functional language to learn]. Jun Mukai. In Japanese. Yen 2,730.<br />
<dd><br />
<br />
<dt>[[Image:Haskell-jp-2.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4797336021 Practical Haskell Programming], Minero Aoki and Nobuo Yamashita. A primer on functional programming for real world programs. In Japanese. Yen 2,940. <br />
<dd><br />
<br />
<dt>[[Image:Purely_Functional_Data_Structures.jpg|frameless|right|Cover]] [https://www.amazon.com/Purely-Functional-Data-Structures-Okasaki/dp/0521663504 Purely Functional Data Structures] [http://web.archive.org/web/20111116194421/www.eecs.usma.edu/webs/people/okasaki/ Chris Okasaki], 232 pp., Cambridge University Press, 1998. ISBN 0-521-63124-6<br />
<dd><br />
From the cover:<BR/> Most books on data structures assume an imperative language like C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Haskell, or Scheme. This book describes data structures and data structure design techniques from the point of view of functional languages. It includes code for a wide assortment both of classical data structures and of data structures developed exclusively for functional languages.This handy reference for professional programmers working with functional languages can also be used as a tutorial or for self-study. [http://web.archive.org/web/20120207054804/www.eecs.usma.edu/webs/people/okasaki/pfds-haskell.tar.gz Haskell source code for the book]<br />
<br />
<DT>[[Функциональное программирование на языке Haskell]]<br />
<br />
<DT>[[Справочник по языку Haskell]]<br />
<br />
<DT>[[Практика работы на языке Haskell]]<br />
<br />
<DT>[[14 занимательных эссе о языке Haskell и функциональном программировании]]<br />
<br />
<dt> <br />
[[Image:Cartea-lui-Dan-Popa-coperta-1.png|frameless|right|Cover]] [http://web.archive.org/web/20081227093758/https://www.edusoft.ro/detalii.php?id=81 Introducere in Haskell 98 prin exemple ]: Dan Popa, 230 pp., Edusoft Bacau, Romania, (Ian, 31, 2007),Romanian, ISBN 978-973-8934-48-1<br />
<dd><b>De pe coperta</b><BR><br />
(ro) Cartea este simultan un manual introductiv de Haskell si o carte auxiliara pentru studentii de la cursul de limbaje formale. Veti avea satisfactia cunoasterii unui limbaj modern (...) in care algoritmul de sortare Quicksort se scrie pe 6 randuri, asa cum se poate vedea de altfel si in imaginea de pe coperta I. (...) Cartea cuprinde o serie de capitole folosite la Universitatea Bacau in calitate de auxiliare de laborator la disciplina Limbaje Formale si Automate.<br />
<br><br />
(en) This book is simultaneously a manual of Haskell and an auxiliary book for the students of the FLA course (Formal Languges and Automata). You will be satisfied by this modern language,Haskell. Why ? Using Haskell the Quicksort algorithm can be writen on 6 lines (or less), as you can see on the cover. And that's not all ... This book is used at Bacau State University, Romania. <br />
<br />
<dt>James Church : [[Image: Getting_Started_with_Haskell_Data_Analysis.png|frameless|right|70px|Cover]] [https://india.packtpub.com/in/big-data-and-business-intelligence/getting-started-haskell-data-analysis Getting Started with Haskell Data Analysis], ISBN13 9781789802863, Paperback/eBook: 160 pages. Packt October 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Every business and organization that collects data is capable of tapping into its own data to gain insights how to improve. Haskell is a purely functional and lazy programming language, well-suited to handling large data analysis problems. This book will take you through the more difficult problems of data analysis in a hands-on manner.<br />
<br />
This book will help you get up-to-speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and progress to more advanced concepts such as understanding the importance of normal distribution. While mathematics is a big part of data analysis, we've tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
By the end of this book, you will have a thorough understanding of data analysis, and the different ways of analyzing data. You will have a mastery of all the tools and techniques in Haskell for effective data analysis.<br />
<br />
<dt>Yogesh Sajanikar : [[Image: Haskell_Cookbook.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-cookbook Haskell Cookbook], ISBN13 9781786461353, Paperback/eBook: 396 pages. Packt (September 2017)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell Cookbook provides recipes that start by illustrating the principles of functional programming in Haskell, and then gradually build up your expertise in creating industrial-strength programs to accomplish any goal. The book covers topics such as Functors, Applicatives, Monads, and Transformers. You will learn various ways to handle state in your application and explore advanced topics such as Generalized Algebraic Data Types, higher kind types, existential types, and type families. The book will discuss the association of lenses with type classes such as Functor, Foldable, and Traversable to help you manage deep data structures.<br />
<br />
<dt>[[Image:HaskellDataAnalysis.png|70px|frameless|right|Cover]] Nishant Shukla: [http://web.archive.org/web/20200108214119/http://haskelldata.com/ <em>Haskell Data Analysis Cookbook</em>], Paperback: 334 pages, Packt, June 2014, English, ISBN-10: 1783286334, ISBN-13: 978-1783286331<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book will take you on a voyage through all the steps involved in data analysis. It provides synergy between Haskell and data modeling, consisting of carefully chosen examples featuring some of the most popular machine learning techniques.<br />
<br />
You will begin with how to obtain and clean data from various sources. You will then learn how to use various data structures such as trees and graphs. The meat of data analysis occurs in the topics involving statistical techniques, parallelism, concurrency, and machine learning algorithms, along with various examples of visualizing and exporting results. By the end of the book, you will be empowered with techniques to maximize your potential when using Haskell for data analysis.<br />
<br />
The [https://github.com/BinRoot/Haskell-Data-Analysis-Cookbook GitHub public repository] contains over 130 practical recipes to accompany every chapter of the book. Use it as a Swiss Army Knife of algorithms and code snippets. Try a recipe a day, like a kata for your mind.<br />
<br />
<dt>Samuli Thomasson: [[Image: HaskellHighPerformanceProgramming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-high-performance-programming Haskell High Performance Programming Book], ISBN 139781786464217, Paperback, 408 pages Packt, September 2016<br />
<dd><br />
<B>Book Description</B><BR> <br />
Haskell, with its power to optimize the code and its high performance, is a natural candidate for high performance programming. It is especially well suited to stacking abstractions high with a relatively low performance cost. This book addresses the challenges of writing efficient code with lazy evaluation and techniques often used to optimize the performance of Haskell programs.<br />
Learn to use parallelism and explore the concept of streaming. This book demonstrates the benefits of running multithreaded and concurrent applications. Next it will guide you through various profiling tools that will help you identify performance issues in your program. <br />
<br />
<br />
<dt> Ryan Lemmer: [[Image:Haskell Design Patterns.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-design-patterns/?utm_source=GC-wiki.haskell.org&utm_medium=pod&utm_campaign=178398872X Haskell Design Patterns], Paperback: 166 pages, Packt, November 2015, English, ISBN-10: 1-783-98872-X, ISBN-13: 9781783988723<br />
<dd><br />
<B>Book Description</B><BR> <br />
Design patterns and idioms can widen our perspective by showing us where to look, what to look at, and ultimately how to see what we are looking at. At their best, patterns are a shorthand method of communicating better ways to code (writing less, more maintainable, and more efficient code).<br />
<br />
This book starts with Haskell 98 and through the lens of patterns and idioms investigates the key advances and programming styles that together make "modern Haskell". Your journey begins with the three pillars of Haskell. Then you'll experience the problem with Lazy I/O, together with a solution. You'll also trace the hierarchy formed by Functor, Applicative, Arrow, and Monad. Next you'll explore how Fold and Map are generalized by Foldable and Traversable, which in turn is unified in a broader context by functional Lenses. You'll delve more deeply into the Type system, which will prepare you for an overview of Generic programming. In conclusion you go to the edge of Haskell by investigating the Kind system and how this relates to Dependently-typed programming.<br />
<br />
<dt> James Church: [[Image:Learning_Haskell_Data_Analysis_cov.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/learning-haskell-data-analysis/?utm_source=GCwiki.haskell.org&utm_medium=pod&utm_campaign=1784394707 Learning Haskell Data Analysis], Paperback: 198 pages, Packt, May 2015, English, ISBN-10: 1-784-39470-7, ISBN-13: 9781784394707<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book provides you with the skills to handle large amounts of data, even if that data is in a less than perfect state. Each chapter in the book helps to build a small library of code that will be used to solve a problem for that chapter.<br />
<br />
The book starts with creating databases out of existing datasets, cleaning that data, and interacting with databases within Haskell in order to produce charts for publications. It then moves towards more theoretical concepts that are fundamental to introductory data analysis, but in a context of a real-world problem with real-world data. As you progress in the book, you will be relying on code from previous chapters in order to help create new solutions quickly. By the end of the book, you will be able to manipulate, find, and analyze large and small sets of data using your own Haskell libraries.<br />
</dt><br />
<br />
<dt> Julien Dehos: [[Image:Book-ellipses-jd.jpg|frameless|right|70px|Cover]] [https://www.editions-ellipses.fr/programmation-fonctionnelle-introduction-applications-haskell-lusage-letudiant-developpeur-p-13083.html La programmation fonctionnelle - Introduction et applications en Haskell à l'usage de l'étudiant et du développeur], 264 pages, Ellipses Références sciences, 2019, French, ISBN: 9782340028777<br />
<dd><br />
Ce livre a pour objectif d’initier à la programmation fonctionnelle en général et au langage Haskell en particulier ; ceci de façon réellement exploitable. Il en présente les principales notions ainsi que différentes applications (intelligence artificielle pour des jeux, application web, convertisseur de fichiers textes, etc.). Enfin, il indique comment mettre en oeuvre le style fonctionnel dans des langages comme C++ et JavaScript.<br />
</dt><br />
<br />
</DL><br />
<br />
===Foundations===<br />
<br />
<DL><br />
<DT>[[Image:TaPL.jpg|frameless|right|Cover]]<br />
[http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=pd_sim_b_4/104-0009163-6568732 Types and Programming Languages] by Benjamin C. Pierce. 645 pages, The MIT Press, (February 1, 2002), English. ISBN 0262162091<br />
<DD>From the cover:<BR><br />
A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of type systems--and of programming languages from a type-theoretic perspective-has important applications in software engineering, language design, high-performance compilers, and security. This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages. The approach is pragmatic and operational; each new concept is motivated by programming examples and the more theoretical sections are driven by the needs of implementations. Each chapter is accompanied by numerous exercises and solutions, as well as a running implementation, available via the Web. Dependencies between chapters are explicitly identified, allowing readers to choose a variety of paths through the material. The core topics include the untyped lambda-calculus, simple type systems, type reconstruction, universal and existential polymorphism, subtyping, bounded quantification, recursive types, kinds, and type operators. Extended case studies develop a variety of approaches to modeling the features of object-oriented languages.<br />
<br />
<DT>[[Image:Advanced_TaPL.jpg|frameless|right|Cover]] [http://www.amazon.com/Advanced-Topics-Types-Programming-Languages/dp/0262162288/ref=pd_sim_b_1/104-0009163-6568732 Advanced Topics in Types and Programming Languages] by Benjamin C. Pierce (Editor), Hardcover: 608 pages, The MIT Press (December 23, 2004), Language: English, ISBN 0262162288.<DD><br />
From the cover:<BR><br />
The study of type systems for programming languages now touches many areas of computer science, from language design and implementation to software engineering, network security, databases, and analysis of concurrent and distributed systems. This book offers accessible introductions to key ideas in the field, with contributions by experts on each topic. The topics covered include precise type analyses, which extend simple type systems to give them a better grip on the run time behavior of systems; type systems for low-level languages; applications of types to reasoning about computer programs; type theory as a framework for the design of sophisticated module systems; and advanced techniques in ML-style type inference. Advanced Topics in Types and Programming Languages builds on Benjamin Pierce's Types and Programming Languages (MIT Press, 2002); most of the chapters should be accessible to readers familiar with basic notations and techniques of operational semantics and type systems -- the material covered in the first half of the earlier book. Advanced Topics in Types and Programming Languages can be used in the classroom and as a resource for professionals. Most chapters include exercises, ranging in difficulty from quick comprehension checks to challenging extensions, many with solutions.<br />
<br />
<DT>[http://web.archive.org/web/20160320032411/www.cs.cmu.edu/~rwh/plbook/ Programming Languages: Theory and Practice] by Robert Harper. (Draft).<br />
<DD>A working draft of a planned book on the theoretical foundations of practical programming languages.<br />
<br />
<DT>[https://www.amazon.com/Computational-Semantics-Functional-Programming-Eijck/dp/0521757606 Computational Semantics and Type Theory]<br />
by Jan van Eijck. Draft.<br />
<DD>[http://homepages.cwi.nl/~jve/cs/ Website].<br />
<br />
<DT>[http://www.paultaylor.eu/stable/Proofs+Types.html Proofs and Types]<br />
by Jean-Yves Girard translated and with appendices by Paul Taylor and Yves Lafont.<br />
<DD><br />
Based on a short graduate course on typed lambda-calculus given at the Universit Paris VII in the autumn term of 1986-7.<br />
<br />
<DT>[http://web.archive.org/web/20170511031828/foswiki.cs.uu.nl/foswiki/Techno/ProgrammingLanguageTheoryTextsOnline Programming language theory texts online]<br />
<DD><br />
Collection of online programming language theory texts maintained by Frank Atanassow<br />
<br />
<DT>[http://www.cse.chalmers.se/research/group/logic/book/ Programming in Martin-Löf's Type Theory: An Introduction] by Bengt Nordström, Kent Petersson and Jan M. Smith. 1990.<br />
<DD><br />
<br />
</DL><br />
<br />
===Monadic Programming===<br />
<br />
<DL><br />
<br />
<DT>[[Image:Coperta5.jpg|frameless|right|75px|Haskell - PIM]] [[Practica_interpretarii_monadice|Practical monadic interpretation]] by Dan Popa , Language: Romanian<br />
<br />
<DD><br />
Foreword of the book (en):<br />
<br />
I am delighted to introduce this book on the use of monads in Haskell as a way of structuring interpreters. In the early days, Haskell's most distinctive feature was lazy evaluation. Laziness forced us to take a pure approach to input/output, which meant that Haskell's I/O was initially rather weak. This weakness ultimately proved a strength, however, because it led us to the discovery that monads were not just an abstract mathematical concept, but were immediately applicable as a powerful program structuring mechanism.<br />
<br />
Monadic programming is not just to do with input/output: it is much more powerful. That is why I am pleased to see this book, which describes in some detail how to write a language interpreter using a monadic approach.<br />
<br />
In retrospect, the discovery of monads as a practical programming pattern is one of Haskell's most substantial contributions to the world of programming -- and it is one that you will share if you work through this book.<br />
<br />
I am also very happy to see Haskell growing in popularity among our brothers and sisters in Eastern Europe, and in Romania in particular. Enjoy!<br />
<br />
Simon P.J.<br />
</DL><br />
<br />
===Mathematics===<br />
<br />
See [[Books and tutorials/Mathematics]]<br />
<br />
===Miscellaneous===<br />
<br />
[[Real World #haskell]]<br />
<br />
===Videos===<br />
<br />
<dt>Richard Cook : [[Image: Building-an-Application-with-Functional-Haskell-Video.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/building-application-functional-haskell-video Building an Application with Functional Haskell (Video)], ISBN13 9781787285088, Course Length 2 hours 9 minutes. Packt (August 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video is specifically aimed at anybody who knows the essentials of the Haskell programming language and who is interested in moving onto developing real programs that will make use of file I/O, command-line parsers and various third-party packages. This course will take you through the complete journey from writing your first Haskell program to getting familiarized with Haskell and all its functionalities.<br />
<br />
<dt>Richard Cook : [[Image: Writing_Haskell_Programs.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/writing-haskell-programs-video Writing Haskell Programs (Video)], ISBN13 9781787283329, Video Length 2 hours and 43 minutes. Packt (May 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This course builds on the foundations provided by the Fundamentals of Practical Haskell Programming course and helps to bridge the gap between introductory and advanced Haskell by teaching you how to manage and develop complex programs. We'll also dispel the myth that Haskell is only useful for toy programs.<br />
<br />
<dt>Richard Cook : [[Image: Fundamentals_of_Practical_Haskell_Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/fundamentals-practical-haskell-programming-video Fundamentals of Practical Haskell Programming (Video)], ISBN13 9781787288768, Video Length 2 hours and 59 minutes. Packt (March 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video course will take you through all the concepts of functional programming (FP) and Haskell language. First, we’ll address all the problems with FP and Haskell. Then we’ll help you distinguish the difference between FP and Haskell. We’ll then guide you through Haskell in depth. We’ll help you create your first Haskell program. You’ll then be given a brief insight into GHCi (Glasgow Haskell Compiler). Later we’ll explore the different values, expressions and programs in Haskell in depth.<br />
<br />
<dt> [[Image: Haskell Data Analysis Made Easy.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/haskell-data-analysis-made-easy Haskell: Data Analysis Made Easy], ISBN13 9781787283633, Course Length 7 hours 30 minutes. Packt (February 2017)<br />
<dd><br />
<B>Course Description</B><BR><br />
This course will introduce the basic concepts of Haskell and move on to discuss how Haskell can be used to solve the issues by using the real-world data.<br />
The course will guide you through the installation procedure, after you have all the tools that you require in place, you will explore the basic concepts of Haskell including the functions, and the data structures.<br />
With a good hold on the basics of Haskell and data analysis, you will then be introduced to advanced concepts of data analysis such as Kernel Density Estimation, Hypothesis testing, Regression analysis, text analysis, clustering, Naïve Bayes Classification, and Principal Component Analysis.<br />
<br />
<dt>Samuel Gélineau : [[Image: Mastering Haskell Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/mastering-haskell-programming-video Mastering Haskell Programming (Video)], ISBN13 9781786465016, Course Length 6 hours 4 minutes. Packt (February 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
In this course, you’ll discover different ways to structure interactions between the program and the outside world. We’ll look at some subtler aspects of the IO monad, such as lazy IO and unsafePerformIO. In addition to the IO monad, we’ll also check out two other structured forms of interaction: streaming libraries and functional reactive programming.<br />
Then we explore parallel, concurrent, and distributed programming. Thanks to purity, Haskell is especially well-suited for the first two, and so there are a number of approaches to cover. As for distributed programming, we focus on the idea of splitting a large monolithic program into smaller microservices, asking whether doing so is a good idea. We’ll also consider a different way of interacting with other microservices, and explore an alternative to microservices.<br />
<br />
<dt>James Church : [[Image:Advanced_data.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/advanced-data-analysis-haskell-video Advanced Data Analysis with Haskell Video], ISBN13 9781785287237, Course Length 4 hours 4 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
In this video, you will be guided on how to find correlations in data, as well as multiple dependent variables. You will be given a theoretical overview of the types of regression and we’ll show you how to install the LAPACK and HMatrix libraries. By the end of the first part, you’ll be familiar with the application of N-grams and TF-IDF.<br />
Once you’ve learned how to analyze data, the next step is organizing that data with the help of machine learning algorithms. You will be briefed on the mathematics and statistical theorems such as Baye’s law and its application, as well as eigenvalues and eigenvectors using HMatrix.<br />
By the end of this course, you’ll have an understanding of data analysis, different ways to analyze data, and the various clustering algorithms available. You’ll also understand Haskell and will be ready to write code with it.<br />
<br />
<dt>Hakim Cassimally : [[Image: Learning_Haskell_Programming.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/learning-haskell-programming Learning Haskell Programming Video], ISBN13 9781786465542, Course Length 4 hours 10 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
This video would begin with the fundamentals and building blocks of Haskell programming language with special emphasis on functional programming. It will be covering how Haskell variables, syntax work alongwith Haskell datatypes and functions.<br />
You will learn how to solve programming problems while creating an application with hands-on experience. You will then move on to learning writing expressions and high-order functions.<br />
At the end of the video, you will be able to build a complete application with Haskell alongwith learning the important functionalities.<br />
<br />
<dt>James Church: [[Image: GettingStartedWithHaskellDataAnalysis1.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/getting-started-haskell-data-analysis-video Getting Started with Haskell Data Analysis Video], Course Length: 3 hours 18 minutes, Packt, July 2016, English, ISBN-13: 9781785880841<br />
<dd><br />
<B>Course Description</B><BR> <br />
Data analysis is part computer science and part statistics. An important part of data analysis is validating your assumptions with real-world data to see if there is a pattern, or a particular user behavior that you can validate. This video course will help you get up to speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and onto more advanced concepts like understanding the importance of normal distribution. Whilst mathematics is a big part of data analysis, we’ve tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
==Joke==<br />
<br />
<DL><br />
<dt>[[Image:FunctionalIkamusume.jpg|frameless|right|70px|Cover]] Team "Referential Transparent Sea Keepers": [http://web.archive.org/web/20171224114748/www.paraiso-lang.org/ikmsm/ <em>Functional Ikamusume</em>]<br />
[http://web.archive.org/web/20171224043722/www.paraiso-lang.org/ikmsm/books/index.html <em>book series</em>], Japanese<br />
<dd><B>Book Description</B><BR><br />
Functional Ikamusume book series provides a forum for researchers, developers, and anime-watchers to publish their latest work, articles, and “mousou (妄想)” on the design, implementations, principles, and uses of functional programming and Ikamusume. The book series covers the entire spectrum of work, from practice to theory, from frank introduction of functional programming to latest research work, from Ikamusume with some functional flavor to functional programming with some Ikamusume flavor. Let’s enjoy writing articles on functional programming in frank “geso” style de-geso!!<br />
<br />
Past books are written entirely in Japanese, and books are planned to be sold in Japan, but we also accept articles in English. For more information on functional Ikamusume, see the links above (all in Japanese), or ask @xhl_kogitsune or [http://web.archive.org/web/20171224051807/www.paraiso-lang.org/ikmsm/members.html "other members"] on twitter, or xhlkogitsune on Skype. You don’t have to be worried about what is Functional Ikamusume —— she is just Ikamusume who loves functional programming, as you love it.<br />
<br />
If you are interested in writing Functional Ikamusume articles, please contact xhlkogitsune on Skype or the authors on twitter. You can use Japanese or English for discussion. A text chat room is on Skype, and I’ll invite you to the chat room. While the chat is currently in Japanese, most participants can read/write English.<br />
<br />
</DL></div>Tschrijvershttps://wiki.haskell.org/index.php?title=File:Soar_with_Haskell_cover.jpg&diff=66504File:Soar with Haskell cover.jpg2024-02-02T12:51:19Z<p>Tschrijvers: </p>
<hr />
<div>Soar with Haskell cover</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Books&diff=66503Books2024-02-02T12:48:42Z<p>Tschrijvers: /* Textbooks */ Add "Soar with Haskell"</p>
<hr />
<div>Books covering many aspects of Haskell.<br />
<br />
In addition to this wiki page, many English books related to Haskell are listed in a <br />
[https://www.extrema.is/articles/haskell-books "Haskell Books index"]. An<br />
[https://www.extrema.is/articles/tag/index:haskell-books.rss "RSS feed"]<br />
can be used to receive notifications when new books are added to the index.<br />
<br />
==Language and library definition==<br />
<br />
<DL><br />
<br />
<DT>[[Image:Haskell_98_Language_and_Libraries.jpg|frameless|right|Cover]]<br />
Simon Peyton Jones: [https://www.haskell.org/definition/haskell98-report.pdf "Haskell 98 language and libraries: the Revised Report"], Cambridge University Press, 2003, Hardback, 272 pages, ISBN 0521826144, £45.00<br />
<DD><br />
<B>Book Description</B><BR> <br />
Haskell is the world's leading lazy functional programming language,<br />
widely used for teaching, research, and applications. The language<br />
continues to develop rapidly, but in 1998 the community decided to<br />
capture a stable snapshot of the language: Haskell 98. All Haskell<br />
compilers support Haskell 98, so practitioners and educators alike<br />
have a stable base for their work. This book constitutes the agreed<br />
definition of the Haskell 98, both the language itself and its<br />
supporting libraries. It has been considerably revised and refined<br />
since the original definition, and appears in print for the first<br />
time. It should be a standard reference work for anyone involved in<br />
research, teaching, or application of Haskell.<br />
<br />
The entire language definition is also available online:<br />
[[Language_and_library_specification|Language and library<br />
specification]].<br />
</DL><br />
<br />
==Textbooks==<br />
<br />
<DL><br />
<dt>Tom Schrijvers : [https://www.packtpub.com/product/soar-with-haskell/9781805128458 Soar with Haskell], ISBN13 9781805128458, Paperback/eBook: 418 pages. Packt (December 2023). <br />
<dd><br />
<B>Book Description</B><BR><br />
With software systems reaching new levels of complexity and programmers aiming for the highest productivity levels, software developers and language designers are turning toward functional programming because of its powerful and mature abstraction mechanisms. This book will help you tap into this approach with Haskell, the programming language that has been leading the way in pure functional programming for over three decades. The book begins by helping you get to grips with basic functions and algebraic datatypes, and gradually adds abstraction mechanisms and other powerful language features. Next, you’ll explore recursion, formulate higher-order functions as reusable templates, and get the job done with laziness. As you advance, you’ll learn how Haskell reconciles its purity with the practical need for side effects and comes out stronger with a rich hierarchy of abstractions, such as functors, applicative functors, and monads. Finally, you’ll understand how all these elements are combined in the design and implementation of custom domain-specific languages for tackling practical problems such as parsing, as well as the revolutionary functional technique of property-based testing. By the end of this book, you’ll have mastered the key concepts of functional programming and be able to develop idiomatic Haskell solutions.<br />
<br />
<dt>John Whitington : [[Image: Hftvb-cover.jpg|frameless|right|70px|Cover]] [https://haskellfromtheverybeginning.com/ Haskell from the Very Beginning], ISBN13 9780957671133, Paperback/eBook: 216 pages. Coherent Press (October 2019)<br />
<dd><br />
<B>Book Description</B><BR><br />
In Haskell from the Very Beginning John Whitington takes a no-prerequisites approach to teaching the basics of a modern general-purpose programming language. Each small, self-contained chapter introduces a new topic, building until the reader can write quite substantial programs. There are plenty of questions and, crucially, worked answers and hints.<br />
<br />
Haskell from the Very Beginning will appeal both to new programmers, and to experienced programmers eager to explore functional languages such as Haskell. It is suitable both for formal use within an undergraduate or graduate curriculum, and for the interested amateur.<br />
<br />
<dt>Alexander Granin : [[Image: fdaa-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/functional-design-and-architecture Functional Design and Architecture, Second Edition], ISBN13 9781617299612, Paperback/eBook: 575 pages (estimated). Manning Publications (Fall December 2021)<br />
<dd><br />
<B>Book Description</B><BR><br />
Functional Design and Architecture is a practical book that covers the biggest gap in the Haskell ecosystem: how to design real-world applications with low complexity and low risks. Application architectures, design patterns, best practices, methodologies and approaches - everything you need to write a high-quality code. The book introduces a new methodology - Functional Declarative Design, - and provides a comprehensive, complete view of Software Engineering in Haskell. It covers all the main topics: requirements analysis, domain-driven design, testing, domain-specific languages, databases, logging, multithreading, type-level programming, and so on.<br />
<br />
This book doesn't introduce you to the Haskell language, but instead, it tells about high-level topics of Software Design. It can be your third Haskell book.<br />
<br />
This is the second edition of the book.<br />
<br />
<dt>Vitaly Bragilevsky : [[Image: Hid-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/haskell-in-depth Haskell in Depth], ISBN13 9781617295409, Paperback/eBook: 664 pages. Manning Publications (May 2021)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell in Depth is the perfect second book on Haskell. After a quick refresher on Haskell basics, this hands-on guide dives into examples and application scenarios designed to teach how Haskell works and how to apply it correctly. You’ll learn about managing projects with Cabal and Stack, tackle error-handling and testing, and package programs and libraries for production deployment.<br />
<br />
You’ll appreciate coverage of advanced Haskell features including programming polymorphically, working effectively with types, concurrent programming, data processing, web services, and more. Because it’s organized to make specific topics easy to find, you’ll return to this book again and again as your go-to Haskell reference.<br />
<br />
<dt>Will Kurt : [[Image: Gph-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/get-programming-with-haskell Get Programming with Haskell], ISBN13 9781617293764, Paperback/eBook: 616 pages. Manning Publications (March 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Get Programming with Haskell leads you through short lessons, examples, and exercises designed to make Haskell your own. It has crystal-clear illustrations and guided practice. You will write and test dozens of interesting programs and dive into custom Haskell modules. You will gain a new perspective on programming plus the practical ability to use Haskell in the everyday world. (The 80 IQ points: not guaranteed!)<br />
<br />
<dt>[[Image:beginning_haskell.jpg|frameless|right|70px|Cover]] Alejandro Serrano Mena: [http://www.apress.com/9781430262503 <em>Beginning Haskell</em>], Paperback / eBook: 498 pages, Apress (January 2014), English, ISBN: 978-1-43026-250-3<br />
<dd><B>Book Description</B><BR><br />
Beginning Haskell provides a broad-based introduction to the Haskell language, its libraries and environment, and to the functional programming paradigm that is fast growing in importance in the software industry. The book takes a project-based approach to learning the language that is unified around the building of a web-based storefront. Excellent coverage is given to the Haskell ecosystem and supporting tools. These include the Cabal build tool for managing projects and modules, the HUnit and QuickCheck tools for software testing, the Scotty framework for developing web applications, Persistent and Esqueleto for database access, and also parallel and distributed programming libraries.<br />
<br />
<dt>[[Image:Lyah.png|frameless|right|70px|Cover]] Miran Lipovača: [http://www.nostarch.com/lyah.htm <em>Learn You a Haskell for Great Good!</em>], Paperback: 360 pages, No Starch Press (April 2011), English, ISBN: 978-1-59327-283-8<br />
<dd><B>Book Description</B><BR><br />
It's all in the name: Learn You a Haskell for Great Good! is a hilarious, illustrated guide to this complex functional language. Packed with the author's original artwork, pop culture references, and most importantly, useful example code, this book teaches functional fundamentals in a way you never thought possible.<br />
<br />
<dt>[[Image:LearnPhysicsWithFunctionalProgramming_front.webp|frameless|right|70px|Cover]] Scott N. Walck: [https://lpfp.io <em>Learn Physics with Functional Programming: A Hands-on Guide to Exploring Physics with Haskell</em>], Paperback: 648 pages, No Starch Press (January 2023), English, ISBN: 978-1-7185-0166-9<br />
<dd><B>Book Description</B><BR><br />
This book shows how to encode basic theoretical physics in Haskell. The author currently uses it in a computational physics course for physics majors at Lebanon Valley College. It covers Newtonian mechanics, a little special relativity, and electromagnetic theory up to the Maxwell equations. The book<br />
teaches Haskell to people interested in science generally, or physics specifically.<br />
<br />
<dt>[[Image:pih.jpg|frameless|right|70px|Cover]] Graham Hutton: [http://www.cs.nott.ac.uk/~pszgmh/pih.html <em>Programming in Haskell</em>], Paperback: 318 pages, 120 exercises, Cambridge University Press (September 1, 2016), English, ISBN-13: 978-1316626221<br />
<dd><br />
<B>Book Description</B><BR> <br />
This new edition has been extensively updated and expanded to include recent and more advanced features of Haskell, new examples and exercises, selected solutions, and freely downloadable lecture slides and example code. The presentation is clean and simple, while also being fully compliant with the latest version of the language, including recent changes concerning applicative, monadic, foldable and traversable types.<br />
<br />
<dt>[[Image:Rwh-thumb.png|frameless|right|Cover]] Bryan O'Sullivan, Don Stewart, and John Goerzen: [http://book.realworldhaskell.org/ <em>Real World Haskell</em>], Paperback: 700 pages, O'Reilly, November 2008, English, ISBN-10: 0596514980, ISBN-13: 978-0596514983<br />
<dd><br />
See ''[[Real World Haskell]]''. <br />
<br />
<br><br />
<dt>[[Image:pcph-thumb.gif|70px|frameless|right|Cover]] Simon Marlow: [https://simonmar.github.io/pages/pcph.html <em>Parallel and Concurrent Programming in Haskell</em>], Paperback: 322 pages, O'Reilly, August 2013, English, ISBN-10: 1449335942, ISBN-13: 978-1449335946<br />
<dd><br />
<B>Book Description</B><BR> <br />
If you have a working knowledge of Haskell, this hands-on book shows you how to use the language’s many APIs and frameworks for writing both parallel and concurrent programs. You’ll learn how parallelism exploits multicore processors to speed up computation-heavy programs, and how concurrency enables you to write programs with threads for multiple interactions.<br />
<br />
Author Simon Marlow walks you through the process with lots of code examples that you can run, experiment with, and extend. Divided into separate sections on Parallel and Concurrent Haskell, this book also includes exercises to help you become familiar with the concepts presented:<br />
<br />
* Express parallelism in Haskell with the Eval monad and Evaluation Strategies<br />
* Parallelize ordinary Haskell code with the Par monad<br />
* Build parallel array-based computations, using the Repa library<br />
* Use the Accelerate library to run computations directly on the GPU<br />
* Work with basic interfaces for writing concurrent code<br />
* Build trees of threads for larger and more complex programs<br />
* Learn how to build high-speed concurrent network servers<br />
* Write distributed programs that run on multiple machines in a network <br />
<br />
<br />
<DT>[[Image:The_Haskell_School_of_Expression.jpg|frameless|right|Cover]] Paul Hudak: [http://web.archive.org/web/20190705205338/https://www.cs.yale.edu/homes/hudak/SOE/ <EM>The Haskell School of Expression: Learning Functional Programming through Multimedia</EM>], Cambridge University Press, New York, 2000, 416pp, 15 line diagrams, 75 exercises, Paperback $29.95, ISBN 0521644089, Hardback $74.95, ISBN 0521643384<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book teaches functional programming as a way of thinking and<br />
problem solving, using Haskell, the most popular purely functional<br />
language. Rather than using the conventional mathematical examples<br />
commonly found in other programming language textbooks, the author<br />
draws examples from multimedia applications, including graphics,<br />
animation, and computer music, thus rewarding the reader with working<br />
programs for inherently more interesting applications. Aimed at both<br />
beginning and advanced programmers, this tutorial begins with a gentle<br />
introduction to functional programming and moves rapidly on to more<br />
advanced topics. An underlying theme is the design and implementation<br />
of <em>domain specific languages</em>, using three examples: FAL (a Functional<br />
Animation Language), IRL (an Imperative Robot Language), and MDL (a<br />
Music Description Language). Details about programming in Haskell<br />
are presented in boxes throughout the text so they can be easily<br />
referred to and found quickly.<br />
<br />
The book's [http://web.archive.org/web/20110720122354/http://plucky.cs.yale.edu/soe/ website] contains source files for all programs in the text, as well as the graphics libraries to run them under Windows and Linux platforms. It also contains PowerPoint slides useful for<br />
teaching a course using the textbook.<br />
<br />
*There is a review of SOE on this wiki: [[The Monad.Reader/Issue3/SoE Review]].<br />
<br />
<DT>[[Image:The_Craft_of_Functional_Programming.jpg|frameless|right|Cover]] Simon Thompson: [http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/ <EM>Haskell: The Craft of Functional Programming</EM>], Second Edition, Addison-Wesley, 507&nbsp;pages, paperback, 1999. ISBN 0-201-34275-8.<br />
<dd><br />
<B>Book Description</B><BR> <br />
The second edition of Haskell: The Craft of Functional Programming is essential reading for beginners to functional programming and newcomers to the Haskell programming language. The emphasis is on the process of crafting programs and the text contains many examples and running case studies, as well as advice an program design, testing, problem solving and how to avoid common pitfalls. <br />
<br />
Building on the strengths of the first edition, the book includes many new and improved features: <br />
*Complete coverage of Haskell 98, the standard version of Haskell which will be stable and supported by implementations for years to come. <br />
*An emphasis on software engineering principles, encouraging a disciplined approach to building reusable libraries of software components. <br />
*Detailed coverage of the Hugs interpreter with an appendix covering other implementations. <br />
*A running case study of pictures emphasizes the built-in functions which appear in the standard prelude and libraries. It is also used to give an early preview of some of the more complex language features, such as high-order functions. <br />
*List comprehensions and the standard functions over lists are covered before recursion. <br />
*Early coverage of polymorphism supporting the "toolkit" approach and encouraging the resuse of built-in functions and types. <br />
*Extensive reference material containing details of further reading in books, journals and on the World Wide Web. <br />
*Accompanying Web Site supporting the book, containing all the program code, further teaching materials and other useful resources. <br />
<B>Synopsis</B><BR> <br />
This books introduces Haskell at a level appropriate for those with little or no prior experience of functional programming. The emphasis is on the process of crafting programs, solving problems, and avoiding common errors.<br />
<br />
<DT>[[Image:Bird_TFWH.jpg|frameless|right|70 px|Cover]] Richard Bird: [https://www.cambridge.org/core/books/thinking-functionally-with-haskell/79F91D976F0C7229082325B41824EBBC# <EM>Thinking Functionally with Haskell</EM>], Cambridge University Press, 2014, 354 pp., ISBN-10: 1107452643, ISBN-13: 978-1107452640.<br />
<dd><br />
Richard Bird is famed for the clarity and rigour of his writing. His new textbook, which introduces functional programming to students, emphasises fundamental techniques for reasoning mathematically about functional programs. By studying the underlying equational laws, the book enables students to apply calculational reasoning to their programs, both to understand their properties and to make them more efficient. The book has been designed to fit a first- or second-year undergraduate course and is a thorough overhaul and replacement of his earlier textbooks. It features case studies in Sudoku and pretty-printing, and over 100 carefully selected exercises with solutions.<br />
<br />
<DT>[[Image:Introduction_to_Functional_Programming_Systems_Using_Haskell.jpg|frameless|right|Cover]] Antony Davie: <EM>[https://www.amazon.com/Introduction-Programming-INTRODUCTION-PROGRAMMING-Jun-18-1992/dp/B003Q5UPH4 An Introduction to Functional Programming Systems Using Haskell]</EM> Cambridge University Press, 1992. ISBN 0-521-25830-8 (hardback). ISBN 0-521-27724-8 (paperback).<br />
<dd>Cover:<br />
<br />
Functional programming is a style of programming that has become increasingly popular during the past few years.<br />
Applicative programs have the advantage of being almost immediately expressible as functional descriptions; they can<br />
be proved correct and transformed through the referential transparency property.<br />
<br />
This book presents the basic concepts of functional programming, using the language Haskell for examples. The author<br />
incorporates a discussion of lambda calculus and its relationship with Haskell, exploring the implications for<br />
raparallelism. Contents: SASL for Beginners / Examples of SASL Programming / More Advanced Applicative Programming<br />
Techniques / Lambda Calculus / The Relationship Between Lambda Calculus and SASL / Program Transformation and<br />
Efficiency / Correctness, Equivalence and Program Verification / Landin's SECD Machine and Related<br />
Implementations / Further Implementation Techniques / Special Purpose Hardware / The Applicative Style of<br />
Semantics / Other Applicative Languages / Implications for Parallelism / Functional Programming in Von Neumann<br />
Languages <br />
<br />
<DT>[[Image:Algorithms_A_Functional_Approach.jpg|frameless|right|Cover]] Fethi Rabhi and Guy Lapalme: [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html <EM> Algorithms: A functional programming approach</EM>], <br />
Addison-Wesley, 235&nbsp;pages, paperback, 1999. ISBN 0-201-59604-0<BR><br />
<DD><br />
<B>Book Description</B><BR> <br />
The authors challenge more traditional methods of teaching algorithms<br />
by using a functional programming context, with Haskell as an<br />
implementation language. This leads to smaller, clearer and more<br />
elegant programs which enable the programmer to understand the<br />
algorithm more quickly and to use that understanding to explore<br />
alternative solutions. <br><br />
<b>Key features:</b><br />
*Most chapters are self-contained and can be taught independently from each other.<br />
*All programs are in Haskell'98 and provided on a WWW site.<br />
*End of chapter exercises throughout.<br />
*Comprehensive index and bibliographical notes.<br />
<B>Synopsis</B><BR> <br />
The book is organised as a classic algorithms book according to topics<br />
such as Abstract Data Types, sorting and searching. It uses a<br />
succession of practical programming examples to develop in the reader<br />
problem-solving skills which can be easily transferred to other<br />
language paradigms. It also introduces the idea of capturing<br />
algorithmic design strategies (e.g. Divide-and-Conquer, Dynamic<br />
Programming) through higher-order functions.<br><br />
<b>Target audience</b><br><br />
The book is intended for computer science students taking algorithms<br />
and/or (basic or advanced) functional programming courses.<br />
<br />
<dt>[[Image:Fun_of_Programming.jpg|frameless|right|Cover]] Jeremy Gibbons and Oege de Moor (eds.): <em>[https://www.amazon.com/Fun-Programming-Cornerstones-Computing/dp/0333992857 The Fun of Programming]</em>,Palgrave, 2002, 288 pages. ISBN 0333992857.<br />
<dd><br />
<b>Book description:</b><br><br />
In this textbook, leading researchers give tutorial expositions on the current state of the art of functional<br />
programming. The text is suitable for an undergraduate course immediately following an introduction to<br />
functional programming, and also for self-study. All new concepts are illustrated by plentiful examples,<br />
as well as exercises. A [http://web.comlab.ox.ac.uk/oucl/publications/books/fop/ website] gives access to accompanying software.<br />
<br />
<dt>Simon Peyton Jones: [https://simon.peytonjones.org/publications-1980/#the-implementation-of-functional-programming-languages <em>Implementation of Functional Programming Languages</em>], 500 pages, Prentice-Hall, 1987. ISBN 0134533259.<br />
<dd><br />
This 1987 book is now out of print, but it is now available [https://www.microsoft.com/en-us/research/uploads/prod/1987/01/slpj-book-1987-r90.pdf online] in its entirety.<br />
<br />
<dt>Simon Peyton Jones, David Lester: [http://www.amazon.com/Implementing-Functional-Languages-Prentice-Hall-International/dp/0137219520/sr=1-1/qid=1162002704/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Implementing Functional Languages</em>], Paperback: 288 pages, Prentice Hall (August 1992), English, ISBN 0137219520 <br><br />
<dd><br />
The book is out of print. The full sources and a PDF version are <br />
[https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.109.8027&rep=rep1&type=pdf available for free].<br />
<br />
This book gives a practical approach to understanding the<br />
implementations of non-strict functional languages using lazy graph<br />
reduction. The emphasis of the book is on building working prototypes of<br />
several functional language implementations (template- instantiation,<br />
G-Machine, TIM, parallel G-Machine. In each case the authors provide a<br />
complete working prototype of a particular implementation, and then lead<br />
the reader through a sequence of improvements which expand its scope.<br />
This enables readers to develop, modify and experiment with their own<br />
implementations and for use as a source of practical laboratory work<br />
material.<br />
<br />
<dt>[[Image:TTFP.jpg|frameless|right|Cover]] Simon Thompson: [http://www.amazon.com/Functional-Programming-International-Computer-Science/dp/0201416670/sr=1-1/qid=1162002856/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Type Theory and Functional Programming</em>], Addison-Wesley, 1991. ISBN 0-201-41667-0. Hardcover: 388 pages.<br />
<dd><br />
Now out of print, the original version is available [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ here].<br />
<br />
<em>Preface</em>:<br />
Constructive Type theory has been a topic of research interest to computer scientists,<br />
mathematicians, logicians and philosophers for a number of years. For computer scientists it provides<br />
a framework which brings together logic and programming languages in a most elegant and fertile way:<br />
program development and verification can proceed within a single system. Viewed in a different way,<br />
type theory is a functional programming language with some novel features, such as the totality of<br />
all its functions, its expressive type system allowing functions whose result type depends upon the<br />
value of its input, and sophisticated modules and abstract types whose interfaces can contain logical<br />
assertions as well as signature information. A third point of view emphasizes that programs (or<br />
functions) can be extracted from proofs in the logic.<br />
<br />
<DT>[[Image:Uma_Abordagem_Pratica.jpg|frameless|right|Cover]] Claudio Cesar de Sá and Marcio Ferreira da Silva: <em> Haskell: Uma Abordagem Prática</em>, [http://www.novatec.com.br Novatec Editora Ltda.], 2006, 296 pages, ISBN 85-7522-095-0. The price is R$ 62,00 (in Reais). Language: Portuguese<br />
<dd><br />
This book is being published by Novatec Editora Ltda. You can access directly [http://www.novateceditora.com.br/livros/haskell/ here].<br />
<br><br />
<b>Book description:</b><br><br />
This book brings a comprehensive vision of Haskell language. No <br />
knowledge in another functional programming language is expected. In <br />
addition, no background in programming is required. The book presents <br />
issues from basic up to an intermediate level; it also includes some <br />
advanced aspects of Haskell. The title of the book, <em>Haskell: Uma <br />
Abordagem Prática</em>, in English <em>Haskell: A Practical Approach</em>, is the essence of the book. The result is a text that can be used in courses of programming and paradigms languages. Finally, many practical examples can be found throughout the book.<br />
<br />
An additional page containing comments on this book is found here:<br />
[http://web.archive.org/web/20170702235455/www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell http://www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell].<br />
Other data as bibtex entry, cover's book in several formats, Winhugs-2001 for download, and so on. This page is Portuguese.<br />
<br />
<dt>[[Image:portada.jpg|frameless|right|Cover]] Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo. [http://www.lcc.uma.es/~pepeg/pfHaskell/index.html <em>Razonando con Haskell</em>], Thompson 2004. ISBN 84-9732-277-0. Language: Spanish<br />
<dd><br />
Descripción El objetivo principal de este libro es el de servir como<br />
libro de texto de las asignaturas de Programación Declarativa<br />
correspondientes a los estudios de Informática o Ciencias de la<br />
Computación, y otras ciencias en general ( Matemáticas, Física, etc.).<br />
El texto es fruto de una larga experiencia docente de los autores dentro<br />
de las distintas asignaturas que desarrollan la Programación Funcional<br />
en distintas titulaciones de la Universidad de Málaga. Aún así, su<br />
lectura no queda condicionada a un conocimiento previo sobre lenguajes<br />
de programación (de computadores), ni sobre Informática. De esta forma,<br />
el libro puede ser utilizado por todo aquel que desee tener un<br />
conocimiento amplio sobre la Programación Funcional. <br />
<br />
<dt>[[Image:haskell-jp.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4839919623 Haskell Primer: The first functional language to learn]. Jun Mukai. In Japanese. Yen 2,730.<br />
<dd><br />
<br />
<dt>[[Image:Haskell-jp-2.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4797336021 Practical Haskell Programming], Minero Aoki and Nobuo Yamashita. A primer on functional programming for real world programs. In Japanese. Yen 2,940. <br />
<dd><br />
<br />
<dt>[[Image:Purely_Functional_Data_Structures.jpg|frameless|right|Cover]] [https://www.amazon.com/Purely-Functional-Data-Structures-Okasaki/dp/0521663504 Purely Functional Data Structures] [http://web.archive.org/web/20111116194421/www.eecs.usma.edu/webs/people/okasaki/ Chris Okasaki], 232 pp., Cambridge University Press, 1998. ISBN 0-521-63124-6<br />
<dd><br />
From the cover:<BR/> Most books on data structures assume an imperative language like C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Haskell, or Scheme. This book describes data structures and data structure design techniques from the point of view of functional languages. It includes code for a wide assortment both of classical data structures and of data structures developed exclusively for functional languages.This handy reference for professional programmers working with functional languages can also be used as a tutorial or for self-study. [http://web.archive.org/web/20120207054804/www.eecs.usma.edu/webs/people/okasaki/pfds-haskell.tar.gz Haskell source code for the book]<br />
<br />
<DT>[[Функциональное программирование на языке Haskell]]<br />
<br />
<DT>[[Справочник по языку Haskell]]<br />
<br />
<DT>[[Практика работы на языке Haskell]]<br />
<br />
<DT>[[14 занимательных эссе о языке Haskell и функциональном программировании]]<br />
<br />
<dt> <br />
[[Image:Cartea-lui-Dan-Popa-coperta-1.png|frameless|right|Cover]] [http://web.archive.org/web/20081227093758/https://www.edusoft.ro/detalii.php?id=81 Introducere in Haskell 98 prin exemple ]: Dan Popa, 230 pp., Edusoft Bacau, Romania, (Ian, 31, 2007),Romanian, ISBN 978-973-8934-48-1<br />
<dd><b>De pe coperta</b><BR><br />
(ro) Cartea este simultan un manual introductiv de Haskell si o carte auxiliara pentru studentii de la cursul de limbaje formale. Veti avea satisfactia cunoasterii unui limbaj modern (...) in care algoritmul de sortare Quicksort se scrie pe 6 randuri, asa cum se poate vedea de altfel si in imaginea de pe coperta I. (...) Cartea cuprinde o serie de capitole folosite la Universitatea Bacau in calitate de auxiliare de laborator la disciplina Limbaje Formale si Automate.<br />
<br><br />
(en) This book is simultaneously a manual of Haskell and an auxiliary book for the students of the FLA course (Formal Languges and Automata). You will be satisfied by this modern language,Haskell. Why ? Using Haskell the Quicksort algorithm can be writen on 6 lines (or less), as you can see on the cover. And that's not all ... This book is used at Bacau State University, Romania. <br />
<br />
<dt>James Church : [[Image: Getting_Started_with_Haskell_Data_Analysis.png|frameless|right|70px|Cover]] [https://india.packtpub.com/in/big-data-and-business-intelligence/getting-started-haskell-data-analysis Getting Started with Haskell Data Analysis], ISBN13 9781789802863, Paperback/eBook: 160 pages. Packt October 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Every business and organization that collects data is capable of tapping into its own data to gain insights how to improve. Haskell is a purely functional and lazy programming language, well-suited to handling large data analysis problems. This book will take you through the more difficult problems of data analysis in a hands-on manner.<br />
<br />
This book will help you get up-to-speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and progress to more advanced concepts such as understanding the importance of normal distribution. While mathematics is a big part of data analysis, we've tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
By the end of this book, you will have a thorough understanding of data analysis, and the different ways of analyzing data. You will have a mastery of all the tools and techniques in Haskell for effective data analysis.<br />
<br />
<dt>Yogesh Sajanikar : [[Image: Haskell_Cookbook.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-cookbook Haskell Cookbook], ISBN13 9781786461353, Paperback/eBook: 396 pages. Packt (September 2017)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell Cookbook provides recipes that start by illustrating the principles of functional programming in Haskell, and then gradually build up your expertise in creating industrial-strength programs to accomplish any goal. The book covers topics such as Functors, Applicatives, Monads, and Transformers. You will learn various ways to handle state in your application and explore advanced topics such as Generalized Algebraic Data Types, higher kind types, existential types, and type families. The book will discuss the association of lenses with type classes such as Functor, Foldable, and Traversable to help you manage deep data structures.<br />
<br />
<dt>[[Image:HaskellDataAnalysis.png|70px|frameless|right|Cover]] Nishant Shukla: [http://web.archive.org/web/20200108214119/http://haskelldata.com/ <em>Haskell Data Analysis Cookbook</em>], Paperback: 334 pages, Packt, June 2014, English, ISBN-10: 1783286334, ISBN-13: 978-1783286331<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book will take you on a voyage through all the steps involved in data analysis. It provides synergy between Haskell and data modeling, consisting of carefully chosen examples featuring some of the most popular machine learning techniques.<br />
<br />
You will begin with how to obtain and clean data from various sources. You will then learn how to use various data structures such as trees and graphs. The meat of data analysis occurs in the topics involving statistical techniques, parallelism, concurrency, and machine learning algorithms, along with various examples of visualizing and exporting results. By the end of the book, you will be empowered with techniques to maximize your potential when using Haskell for data analysis.<br />
<br />
The [https://github.com/BinRoot/Haskell-Data-Analysis-Cookbook GitHub public repository] contains over 130 practical recipes to accompany every chapter of the book. Use it as a Swiss Army Knife of algorithms and code snippets. Try a recipe a day, like a kata for your mind.<br />
<br />
<dt>Samuli Thomasson: [[Image: HaskellHighPerformanceProgramming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-high-performance-programming Haskell High Performance Programming Book], ISBN 139781786464217, Paperback, 408 pages Packt, September 2016<br />
<dd><br />
<B>Book Description</B><BR> <br />
Haskell, with its power to optimize the code and its high performance, is a natural candidate for high performance programming. It is especially well suited to stacking abstractions high with a relatively low performance cost. This book addresses the challenges of writing efficient code with lazy evaluation and techniques often used to optimize the performance of Haskell programs.<br />
Learn to use parallelism and explore the concept of streaming. This book demonstrates the benefits of running multithreaded and concurrent applications. Next it will guide you through various profiling tools that will help you identify performance issues in your program. <br />
<br />
<br />
<dt> Ryan Lemmer: [[Image:Haskell Design Patterns.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-design-patterns/?utm_source=GC-wiki.haskell.org&utm_medium=pod&utm_campaign=178398872X Haskell Design Patterns], Paperback: 166 pages, Packt, November 2015, English, ISBN-10: 1-783-98872-X, ISBN-13: 9781783988723<br />
<dd><br />
<B>Book Description</B><BR> <br />
Design patterns and idioms can widen our perspective by showing us where to look, what to look at, and ultimately how to see what we are looking at. At their best, patterns are a shorthand method of communicating better ways to code (writing less, more maintainable, and more efficient code).<br />
<br />
This book starts with Haskell 98 and through the lens of patterns and idioms investigates the key advances and programming styles that together make "modern Haskell". Your journey begins with the three pillars of Haskell. Then you'll experience the problem with Lazy I/O, together with a solution. You'll also trace the hierarchy formed by Functor, Applicative, Arrow, and Monad. Next you'll explore how Fold and Map are generalized by Foldable and Traversable, which in turn is unified in a broader context by functional Lenses. You'll delve more deeply into the Type system, which will prepare you for an overview of Generic programming. In conclusion you go to the edge of Haskell by investigating the Kind system and how this relates to Dependently-typed programming.<br />
<br />
<dt> James Church: [[Image:Learning_Haskell_Data_Analysis_cov.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/learning-haskell-data-analysis/?utm_source=GCwiki.haskell.org&utm_medium=pod&utm_campaign=1784394707 Learning Haskell Data Analysis], Paperback: 198 pages, Packt, May 2015, English, ISBN-10: 1-784-39470-7, ISBN-13: 9781784394707<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book provides you with the skills to handle large amounts of data, even if that data is in a less than perfect state. Each chapter in the book helps to build a small library of code that will be used to solve a problem for that chapter.<br />
<br />
The book starts with creating databases out of existing datasets, cleaning that data, and interacting with databases within Haskell in order to produce charts for publications. It then moves towards more theoretical concepts that are fundamental to introductory data analysis, but in a context of a real-world problem with real-world data. As you progress in the book, you will be relying on code from previous chapters in order to help create new solutions quickly. By the end of the book, you will be able to manipulate, find, and analyze large and small sets of data using your own Haskell libraries.<br />
</dt><br />
<br />
<dt> Julien Dehos: [[Image:Book-ellipses-jd.jpg|frameless|right|70px|Cover]] [https://www.editions-ellipses.fr/programmation-fonctionnelle-introduction-applications-haskell-lusage-letudiant-developpeur-p-13083.html La programmation fonctionnelle - Introduction et applications en Haskell à l'usage de l'étudiant et du développeur], 264 pages, Ellipses Références sciences, 2019, French, ISBN: 9782340028777<br />
<dd><br />
Ce livre a pour objectif d’initier à la programmation fonctionnelle en général et au langage Haskell en particulier ; ceci de façon réellement exploitable. Il en présente les principales notions ainsi que différentes applications (intelligence artificielle pour des jeux, application web, convertisseur de fichiers textes, etc.). Enfin, il indique comment mettre en oeuvre le style fonctionnel dans des langages comme C++ et JavaScript.<br />
</dt><br />
<br />
</DL><br />
<br />
===Foundations===<br />
<br />
<DL><br />
<DT>[[Image:TaPL.jpg|frameless|right|Cover]]<br />
[http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=pd_sim_b_4/104-0009163-6568732 Types and Programming Languages] by Benjamin C. Pierce. 645 pages, The MIT Press, (February 1, 2002), English. ISBN 0262162091<br />
<DD>From the cover:<BR><br />
A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of type systems--and of programming languages from a type-theoretic perspective-has important applications in software engineering, language design, high-performance compilers, and security. This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages. The approach is pragmatic and operational; each new concept is motivated by programming examples and the more theoretical sections are driven by the needs of implementations. Each chapter is accompanied by numerous exercises and solutions, as well as a running implementation, available via the Web. Dependencies between chapters are explicitly identified, allowing readers to choose a variety of paths through the material. The core topics include the untyped lambda-calculus, simple type systems, type reconstruction, universal and existential polymorphism, subtyping, bounded quantification, recursive types, kinds, and type operators. Extended case studies develop a variety of approaches to modeling the features of object-oriented languages.<br />
<br />
<DT>[[Image:Advanced_TaPL.jpg|frameless|right|Cover]] [http://www.amazon.com/Advanced-Topics-Types-Programming-Languages/dp/0262162288/ref=pd_sim_b_1/104-0009163-6568732 Advanced Topics in Types and Programming Languages] by Benjamin C. Pierce (Editor), Hardcover: 608 pages, The MIT Press (December 23, 2004), Language: English, ISBN 0262162288.<DD><br />
From the cover:<BR><br />
The study of type systems for programming languages now touches many areas of computer science, from language design and implementation to software engineering, network security, databases, and analysis of concurrent and distributed systems. This book offers accessible introductions to key ideas in the field, with contributions by experts on each topic. The topics covered include precise type analyses, which extend simple type systems to give them a better grip on the run time behavior of systems; type systems for low-level languages; applications of types to reasoning about computer programs; type theory as a framework for the design of sophisticated module systems; and advanced techniques in ML-style type inference. Advanced Topics in Types and Programming Languages builds on Benjamin Pierce's Types and Programming Languages (MIT Press, 2002); most of the chapters should be accessible to readers familiar with basic notations and techniques of operational semantics and type systems -- the material covered in the first half of the earlier book. Advanced Topics in Types and Programming Languages can be used in the classroom and as a resource for professionals. Most chapters include exercises, ranging in difficulty from quick comprehension checks to challenging extensions, many with solutions.<br />
<br />
<DT>[http://web.archive.org/web/20160320032411/www.cs.cmu.edu/~rwh/plbook/ Programming Languages: Theory and Practice] by Robert Harper. (Draft).<br />
<DD>A working draft of a planned book on the theoretical foundations of practical programming languages.<br />
<br />
<DT>[https://www.amazon.com/Computational-Semantics-Functional-Programming-Eijck/dp/0521757606 Computational Semantics and Type Theory]<br />
by Jan van Eijck. Draft.<br />
<DD>[http://homepages.cwi.nl/~jve/cs/ Website].<br />
<br />
<DT>[http://www.paultaylor.eu/stable/Proofs+Types.html Proofs and Types]<br />
by Jean-Yves Girard translated and with appendices by Paul Taylor and Yves Lafont.<br />
<DD><br />
Based on a short graduate course on typed lambda-calculus given at the Universit Paris VII in the autumn term of 1986-7.<br />
<br />
<DT>[http://web.archive.org/web/20170511031828/foswiki.cs.uu.nl/foswiki/Techno/ProgrammingLanguageTheoryTextsOnline Programming language theory texts online]<br />
<DD><br />
Collection of online programming language theory texts maintained by Frank Atanassow<br />
<br />
<DT>[http://www.cse.chalmers.se/research/group/logic/book/ Programming in Martin-Löf's Type Theory: An Introduction] by Bengt Nordström, Kent Petersson and Jan M. Smith. 1990.<br />
<DD><br />
<br />
</DL><br />
<br />
===Monadic Programming===<br />
<br />
<DL><br />
<br />
<DT>[[Image:Coperta5.jpg|frameless|right|75px|Haskell - PIM]] [[Practica_interpretarii_monadice|Practical monadic interpretation]] by Dan Popa , Language: Romanian<br />
<br />
<DD><br />
Foreword of the book (en):<br />
<br />
I am delighted to introduce this book on the use of monads in Haskell as a way of structuring interpreters. In the early days, Haskell's most distinctive feature was lazy evaluation. Laziness forced us to take a pure approach to input/output, which meant that Haskell's I/O was initially rather weak. This weakness ultimately proved a strength, however, because it led us to the discovery that monads were not just an abstract mathematical concept, but were immediately applicable as a powerful program structuring mechanism.<br />
<br />
Monadic programming is not just to do with input/output: it is much more powerful. That is why I am pleased to see this book, which describes in some detail how to write a language interpreter using a monadic approach.<br />
<br />
In retrospect, the discovery of monads as a practical programming pattern is one of Haskell's most substantial contributions to the world of programming -- and it is one that you will share if you work through this book.<br />
<br />
I am also very happy to see Haskell growing in popularity among our brothers and sisters in Eastern Europe, and in Romania in particular. Enjoy!<br />
<br />
Simon P.J.<br />
</DL><br />
<br />
===Mathematics===<br />
<br />
See [[Books and tutorials/Mathematics]]<br />
<br />
===Miscellaneous===<br />
<br />
[[Real World #haskell]]<br />
<br />
===Videos===<br />
<br />
<dt>Richard Cook : [[Image: Building-an-Application-with-Functional-Haskell-Video.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/building-application-functional-haskell-video Building an Application with Functional Haskell (Video)], ISBN13 9781787285088, Course Length 2 hours 9 minutes. Packt (August 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video is specifically aimed at anybody who knows the essentials of the Haskell programming language and who is interested in moving onto developing real programs that will make use of file I/O, command-line parsers and various third-party packages. This course will take you through the complete journey from writing your first Haskell program to getting familiarized with Haskell and all its functionalities.<br />
<br />
<dt>Richard Cook : [[Image: Writing_Haskell_Programs.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/writing-haskell-programs-video Writing Haskell Programs (Video)], ISBN13 9781787283329, Video Length 2 hours and 43 minutes. Packt (May 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This course builds on the foundations provided by the Fundamentals of Practical Haskell Programming course and helps to bridge the gap between introductory and advanced Haskell by teaching you how to manage and develop complex programs. We'll also dispel the myth that Haskell is only useful for toy programs.<br />
<br />
<dt>Richard Cook : [[Image: Fundamentals_of_Practical_Haskell_Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/fundamentals-practical-haskell-programming-video Fundamentals of Practical Haskell Programming (Video)], ISBN13 9781787288768, Video Length 2 hours and 59 minutes. Packt (March 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video course will take you through all the concepts of functional programming (FP) and Haskell language. First, we’ll address all the problems with FP and Haskell. Then we’ll help you distinguish the difference between FP and Haskell. We’ll then guide you through Haskell in depth. We’ll help you create your first Haskell program. You’ll then be given a brief insight into GHCi (Glasgow Haskell Compiler). Later we’ll explore the different values, expressions and programs in Haskell in depth.<br />
<br />
<dt> [[Image: Haskell Data Analysis Made Easy.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/haskell-data-analysis-made-easy Haskell: Data Analysis Made Easy], ISBN13 9781787283633, Course Length 7 hours 30 minutes. Packt (February 2017)<br />
<dd><br />
<B>Course Description</B><BR><br />
This course will introduce the basic concepts of Haskell and move on to discuss how Haskell can be used to solve the issues by using the real-world data.<br />
The course will guide you through the installation procedure, after you have all the tools that you require in place, you will explore the basic concepts of Haskell including the functions, and the data structures.<br />
With a good hold on the basics of Haskell and data analysis, you will then be introduced to advanced concepts of data analysis such as Kernel Density Estimation, Hypothesis testing, Regression analysis, text analysis, clustering, Naïve Bayes Classification, and Principal Component Analysis.<br />
<br />
<dt>Samuel Gélineau : [[Image: Mastering Haskell Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/mastering-haskell-programming-video Mastering Haskell Programming (Video)], ISBN13 9781786465016, Course Length 6 hours 4 minutes. Packt (February 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
In this course, you’ll discover different ways to structure interactions between the program and the outside world. We’ll look at some subtler aspects of the IO monad, such as lazy IO and unsafePerformIO. In addition to the IO monad, we’ll also check out two other structured forms of interaction: streaming libraries and functional reactive programming.<br />
Then we explore parallel, concurrent, and distributed programming. Thanks to purity, Haskell is especially well-suited for the first two, and so there are a number of approaches to cover. As for distributed programming, we focus on the idea of splitting a large monolithic program into smaller microservices, asking whether doing so is a good idea. We’ll also consider a different way of interacting with other microservices, and explore an alternative to microservices.<br />
<br />
<dt>James Church : [[Image:Advanced_data.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/advanced-data-analysis-haskell-video Advanced Data Analysis with Haskell Video], ISBN13 9781785287237, Course Length 4 hours 4 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
In this video, you will be guided on how to find correlations in data, as well as multiple dependent variables. You will be given a theoretical overview of the types of regression and we’ll show you how to install the LAPACK and HMatrix libraries. By the end of the first part, you’ll be familiar with the application of N-grams and TF-IDF.<br />
Once you’ve learned how to analyze data, the next step is organizing that data with the help of machine learning algorithms. You will be briefed on the mathematics and statistical theorems such as Baye’s law and its application, as well as eigenvalues and eigenvectors using HMatrix.<br />
By the end of this course, you’ll have an understanding of data analysis, different ways to analyze data, and the various clustering algorithms available. You’ll also understand Haskell and will be ready to write code with it.<br />
<br />
<dt>Hakim Cassimally : [[Image: Learning_Haskell_Programming.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/learning-haskell-programming Learning Haskell Programming Video], ISBN13 9781786465542, Course Length 4 hours 10 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
This video would begin with the fundamentals and building blocks of Haskell programming language with special emphasis on functional programming. It will be covering how Haskell variables, syntax work alongwith Haskell datatypes and functions.<br />
You will learn how to solve programming problems while creating an application with hands-on experience. You will then move on to learning writing expressions and high-order functions.<br />
At the end of the video, you will be able to build a complete application with Haskell alongwith learning the important functionalities.<br />
<br />
<dt>James Church: [[Image: GettingStartedWithHaskellDataAnalysis1.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/getting-started-haskell-data-analysis-video Getting Started with Haskell Data Analysis Video], Course Length: 3 hours 18 minutes, Packt, July 2016, English, ISBN-13: 9781785880841<br />
<dd><br />
<B>Course Description</B><BR> <br />
Data analysis is part computer science and part statistics. An important part of data analysis is validating your assumptions with real-world data to see if there is a pattern, or a particular user behavior that you can validate. This video course will help you get up to speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and onto more advanced concepts like understanding the importance of normal distribution. Whilst mathematics is a big part of data analysis, we’ve tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
==Joke==<br />
<br />
<DL><br />
<dt>[[Image:FunctionalIkamusume.jpg|frameless|right|70px|Cover]] Team "Referential Transparent Sea Keepers": [http://web.archive.org/web/20171224114748/www.paraiso-lang.org/ikmsm/ <em>Functional Ikamusume</em>]<br />
[http://web.archive.org/web/20171224043722/www.paraiso-lang.org/ikmsm/books/index.html <em>book series</em>], Japanese<br />
<dd><B>Book Description</B><BR><br />
Functional Ikamusume book series provides a forum for researchers, developers, and anime-watchers to publish their latest work, articles, and “mousou (妄想)” on the design, implementations, principles, and uses of functional programming and Ikamusume. The book series covers the entire spectrum of work, from practice to theory, from frank introduction of functional programming to latest research work, from Ikamusume with some functional flavor to functional programming with some Ikamusume flavor. Let’s enjoy writing articles on functional programming in frank “geso” style de-geso!!<br />
<br />
Past books are written entirely in Japanese, and books are planned to be sold in Japan, but we also accept articles in English. For more information on functional Ikamusume, see the links above (all in Japanese), or ask @xhl_kogitsune or [http://web.archive.org/web/20171224051807/www.paraiso-lang.org/ikmsm/members.html "other members"] on twitter, or xhlkogitsune on Skype. You don’t have to be worried about what is Functional Ikamusume —— she is just Ikamusume who loves functional programming, as you love it.<br />
<br />
If you are interested in writing Functional Ikamusume articles, please contact xhlkogitsune on Skype or the authors on twitter. You can use Japanese or English for discussion. A text chat room is on Skype, and I’ll invite you to the chat room. While the chat is currently in Japanese, most participants can read/write English.<br />
<br />
</DL></div>Tschrijvershttps://wiki.haskell.org/index.php?title=User_groups&diff=59508User groups2015-03-10T09:02:15Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:Community]]<br />
<br />
A range of Haskell User Groups are springing up all over.<br />
<br />
== Online communities ==<br />
* [http://www.reddit.com/r/haskell/ Haskell Reddit]<br />
* [http://stackoverflow.com/questions/tagged?tagnames=haskell Haskell on Stack Overflow]<br />
<br />
== User groups ==<br />
<br />
Regular meetings in a particular geographical area. Great if you want to see and meet other Haskellers.<br />
<br />
===North America===<br />
<br />
====West Coast ====<br />
<br />
;[http://socalfp.blogspot.com/ SoCal FP Group]<br />
<br />
;[http://www.meetup.com/sandiegohug/ San Diego Haskell User Group]<br />
:a Haskell User Group for the San Diego and Tijuana region<br />
<br />
;[http://bayfp.org/ The Bay Area Functional Programmers group]<br />
:Meeting monthly in the San Francisco Bay area. See [http://bayfp.org/blog their blog] for more details and news of upcoming meetings.<br />
<br />
;[http://pdxfunc.org PDXfunc: Portland FP Group]<br />
:Monthly meetings of the Portland, Oregon functional programming group. Meetings occur on the second Monday of each month at 7 pm, typically in Downtown/NW Portland.<br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2008-February/038991.html Seattle: Northwest Functional Programming Interest Group]<br />
:a Northwest Functional Programming Interest Group in Seattle.<br />
<br />
;[http://www.meetup.com/Vancouver-Haskell-Unmeetup/ Vancouver Haskell UnMeetup]<br />
:Monthly interactive sessions, (+10) for joining<br />
<br />
====East Coast====<br />
<br />
;[http://groups.google.com/group/bostonhaskell Boston Haskell Users' Group].<br />
:Meets monthly.<br />
<br />
;[http://www.meetup.com/NY-Haskell/ New York Haskell Users Group]<br />
:The NY Haskell Users Group is for all programmers either interested in or experienced with the Haskell programming language. Meets monthly.<br />
<br />
;[http://www.meetup.com/lisp-59/ New York Functional Programmers]<br />
:Come and meet like-minded functional programmers in the New York area.<br />
<br />
;[http://www.meetup.com/Haskell-DC/ Haskell DC]<br />
:Washington DC area Meetup for Haskell.<br />
<br />
;[http://www.lisperati.com/fringedc.html FringeDC Washington]<br />
:Meetings about functional programming languages in Washington DC.<br />
<br />
;[http://groups.google.com/group/AFPUG Atlanta Functional Programming Users Group]<br />
:Meet other functional programmers in the Atlanta area. Join us and geek out!<br />
<br />
;Toronto Haskell User Group<br />
:Haskellers of Toronto, unite! We meet at [https://bentomiso.com/events Bento Miso] on the second Wednesday of every month (check the [https://bentomiso.com/events event page] to be sure; it's usually up-to-date). There is also a small organizational [http://groups.google.com/group/toronto-haskell/ mailing list] you can join to keep up to date.<br />
<br />
;[https://groups.google.com/forum/?fromgroups#!forum/haskellers-montreal Montreal Haskell Users' Group].<br />
:Meets monthly.<br />
<br />
====Central====<br />
<br />
;[http://leibnizdream.wordpress.com/2007/12/22/new-austin-functional-programmers-group-in-2008/ Austin Functional Programmers Group]<br />
:See the [http://groups.google.com/group/austin-fp discussion group] for more.<br />
<br />
;[http://www.meetup.com/Boulder-Haskell-Programmers/ Boulder Haskell Programmers]<br />
: Boulder and Denver (Colorado) area Haskell Programmer Group. Meetings are focused on practical topics faced by working programmers. All experience levels are welcome.<br />
<br />
;[http://groups.google.com/group/real-world-haskell-book-club/browse_thread/thread/3e8e59768c8c50a9 Colorado Area Haskell Study Group]<br />
<br />
;[http://ChicagoHaskell.com Chicago Haskell] — First general meeting in December 2009. — [https://groups.google.com/forum/#!forum/haskell-chicago Mailing List] — [https://twitter.com/ChicagoHaskell @ChicagoHaskell]<br />
<br />
;[http://www.meetup.com/DenHUG/ Denver Area Haskell Users Group] -- DenHUG had it's first meeting on 27 Feb 2010. Next meeting will be 3 Apr 2010.<br />
<br />
;[http://www.meetup.com/Houston-Haskell-Users-Group/ Houston Haskell Users Group] -- Meets the 1st Monday of every month at [https://txrxlabs.org/ TxRx labs]<br />
<br />
;[http://www.lambdalounge.org St. Louis Lambda Lounge] -- Meets the 1st Thursday of the month. Since Dec 2008, Lambda Lounge is a user group in St. Louis organized loosely around the idea of exploring dynamic and functional languages.<br />
<br />
;[http://www.meetup.com/nashkell Nashkell - Nashville Haskell Users Group] <br />
<br />
===Australia===<br />
<br />
;[http://groups.google.com/group/fp-syd FP-SYD, the Sydney (Australia) Functional Programming group]<br />
:FP hackers in Sydney.<br />
<br />
;[http://sites.google.com/site/fpunion/ (FPU) Melbourne Functional Programming Union]<br />
:The FPU is a collective of functional programming language enthusiasts, which has been in operation since 1998. We are based at the University of Melbourne, in the Department of Computer Science and Software Engineering, but we are open to all members of the community. We meet on a regular basis for lively discussions on topics broadly associated with the declarative programming paradigm.<br />
<br />
;[http://bfpg.org/ Brisbane Functional Programming Group (BFPG)] ([http://www.meetup.com/Brisbane-Functional-Programming-Group-BFG/ Meetup page])<br />
:A group for Functional Programming with Haskell, Scala and other languages.<br />
<br />
;[http://meetup.com/PerthFP/ Perth Functional Programmers Meetup]<br />
:A group in Perth, WA for Functional Programming with Haskell, Scala and other languages.<br />
<br />
===Europe===<br />
<br />
==== UK ====<br />
;[http://lambdalounge.org.uk/ Manchester Lambda Lounge]<br />
:We are an active community meeting monthly at the [http://madlab.org.uk/ Madlab] (Manchester Digital Laboratory) to talk about topics in functional programming.<br />
<br />
;[http://www.meetup.com/hoodlums/ Hoodlums - Haskell developer meetup]<br />
:Meets monthly on the second Thursday of the month in Canary Wharf. It is a "Coding Dojo" format where we pick some interesting problem and solve it as a group. <br />
<br />
;[http://www.meetup.com/London-HUG/ London Haskell User Group]<br />
:The main meetings are monthly on the last or fourth Thursday of the month. The group was revived in late 2012.<br />
<br />
;[http://www.meetup.com/ed-lambda/ ed lambda (Edinburgh, UK)]<br />
:For functional programming in general, founded by a Haskeller. First meeting will be September 13th 2010.<br />
<br />
;[http://groups.google.com/group/oxhug OxHUG - the Oxford Haskell Users Group]<br />
:Meets every other week, currently at the Department of Computer Science, University of Oxford. Discussion session followed by adjournment to a local tavern. Aimed at students, graduates, professionals and enthusiasts.<br />
<br />
;[http://groups.google.com/group/fp-southwales fp-southwales], the South Wales Functional Programming User Group<br />
:Starting up in late 2009, based out of Swansea University.<br />
<br />
==== France ====<br />
<br />
;[[Fr/Haskell]]<br />
:The Strasbourg HUG meets monthly in an informal setting. Level is very low and newbies are very welcome.<br />
<br />
==== Netherlands ====<br />
<br />
;[http://dutchhug.nl/ Dutch HUG]<br />
:The Dutch HUG meets monthly in an informal setting.<br />
<br />
==== Belgium ====<br />
<br />
;[[Ghent Functional Programming Group]]<br />
:The Ghent Functional Programming Group will be having its first meeting on April 1, 2010.<br />
<br />
;[https://groups.google.com/forum/#!forum/leuven-haskell Leuven Haskell User Group]<br />
:The Leuven Haskell User Group was launched on March 3, 2015 and meets every two weeks.<br />
<br />
==== Germany ====<br />
<br />
;Berlin HUG<br />
:http://www.meetup.com/berlinhug/<br />
<br />
;Haskell in Frankfurt<br />
: <ul><li>[http://www.meetup.com/Frankfurt-Haskell-User-Group Frankfurt Haskell User Group] meets monthly.</li><li> [http://wiki.lug-frankfurt.de/Programmierworkshop/aktuell Regular Saturday Workshop] taking place every couple of months. Feel free to join us!</li><br />
<br />
;[http://www.iba-cg.de/hal5.html Haskell in Leipzig]<br />
:Hal, they have videos [http://iba-cg.de/haskell.html online].<br />
<br />
;[http://www.haskell-munich.de Haskell in Munich]<br />
: We had our first meeting on Thursday, 29th of September 2011. We are always looking forward to see new people. If you can make it to Munich, consider joing us!<br />
<br />
;Interest for User Groups in Germany<br />
* '''Ulm''': [[HugUlm]]<br />
* '''Mannheim or Heidelberg''': [[User:Cgo|cgo]] ([http://www.haskell.org/haskellwiki/?title=Special:Emailuser&target=Cgo mail])<br />
* '''Konstanz''': [[User:Thkoch|thkoch]]<br />
<br />
==== Switzerland ====<br />
<br />
;[http://www.meetup.com/HaskellerZ/ Haskell User Group Zurich]<br />
:We are meeting once a month to share knowledge of and experience with Haskell.<br />
<br />
;[http://www.meetup.com/Geneva-Haskell-Group/ Geneva Haskell Group]<br />
:We are a Haskell community in Geneva planning to meet up every week.<br />
<br />
==== Italy ====<br />
;[[ItaloHaskell]]<br />
:We had a first meeting in August 2008 and we are planning a second one sometime during the 2008/2009 Autumn/Winter season.<br />
<br />
==== Iceland ====<br />
<br />
;[[Reykjavik Haskell User Group]] Iceland<br />
;[http://groups.google.com/group/haskell-is Currently recruiting members]<br />
<br />
==== Poland ====<br />
;[https://plus.google.com/u/0/communities/103183708602453146804 HUG Warsaw] <br />
We are the successors to the Warsaw Functional Society (Warszawskie Towarzystwo Funkcyjne) and as such we welcome any functional programmers and enthusiasts, though the focus of the group is Haskell. We (hope to) have rather informal, but regular meetings in Warsaw, Poland.<br />
<br />
==== Ukraine ====<br />
;[https://groups.google.com/forum/#!forum/ltu-kiev LtU-Kiev community]<br />
:Irregular meetups, usually with prepared talks on Haskell and other FP topics.<br />
;[http://ro-che.info/odhug Odessa Haskell User Group]<br />
:Regular informal meetups (approximately once a month) in a pub or cafe<br />
<br />
==== Hungary ====<br />
<br />
;[http://www.meetup.com/Bp-HUG Budapest Haskell User Group]<br />
:The Haskell User Group is a group of Haskell enthusiasts who are interested in sharing their knowledge and meeting people who share similar interests. We had our first meeting in September 2013.<br />
<br />
==== Norway ====<br />
<br />
;[http://www.meetup.com/Oslo-Haskell/ Osλo Haskell]<br />
:Osλo Haskell is a group for Haskellers and people interested in Haskell and related languages in and around Oslo. We had our first meeting in March 2014.<br />
<br />
=== Israel ===<br />
<br />
;[[IsraelHaskell]] User Group<br />
:[http://article.gmane.org/gmane.comp.lang.haskell.cafe/28877 Are getting organised].<br />
<br />
=== Russia ===<br />
<br />
;[http://ruhaskell.org/ Russian community of Haskell-developers]<br />
;[http://spbhug.folding-maps.org Saint-Petersburg Haskell User Group]<br />
;[https://groups.google.com/forum/#!forum/mskhug Moscow Haskell User Group]<br />
;[https://groups.google.com/forum/#!aboutgroup/haskell-russian haskell-russian mailing list]<br />
<br />
=== Turkey ===<br />
<br />
;[http://groups.google.com/group/core-haskell?lnk=srg Turkey Haskell Programmer's Group]<br />
:Formed by Turkish Functional Programmers, the group began to communicate via an e-mail list opened by core.gen.tr. The first contribution is hlibev project by Aycan iRiCAN.<br />
<br />
;[http://bilfp.wikidot.com/ BILFP (Bilkent University Comp. Eng. Dept. Functional Programming Society)] Turkey <br />
:Project aims to improve people's knowledge and encourage the use of functional programming languages &mdash; especially in Turkey. Group is open to functional-programming-related discussions and establishes related presentations at Bilkent University that are open to anybody.<br />
<br />
===South America===<br />
<br />
====Brazil====<br />
;[[User_groups/Brazil|Grupo Brasileiro de Usuários de Haskell]]<br />
: Grupo criado para reunir os desenvolvedores e entusiastas que utilizam Haskell no Brasil<br />
<br />
==== Bolivia ====<br />
; [https://www.facebook.com/groups/111518795538430/ Comunidad Haskell San Simon (CHSS)]<br />
: Haskell user group for Bolivia and spanish speaking community<br />
<br />
===Asia===<br />
<br />
;[http://lisp.org.cn/en/ China Lisp User Group]<br />
:China Lisp User Group (CLUG) is the earliest founded Lisp user group in China. <br />
<br />
;[http://www.starling-software.com/en/tsac.html Tokyo Society for the Application of Currying]<br />
<br />
;[http://www.meetup.com/HK-Functional-programming/ Hong Kong Functional Programming User Meetup Group]<br />
<br />
===Africa===<br />
<br />
====South Africa====<br />
; [http://www.meetup.com/lambda-luminaries/ Lambda Luminaries] : Functional programming user group based in Centurion, Gauteng.<br />
<br />
== Workshops/meet ups ==<br />
<br />
Less regular, and move around. Usually have a few talks from invited speakers.<br />
See the [[Haskell]] homepage for a list of upcoming events.<br />
<br />
== Hackathons ==<br />
<br />
Getting together to squash bugs and write new stuff. For a list of past and upcoming hackathons, see the [[Hackathon]] page.<br />
<br />
== Conferences ==<br />
<br />
See the [[Haskell_in_research#Conferences|Haskell in research]] and [[Conferences]] page for academic workshops and conferences<br />
focusing on Haskell and related technology.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Haskell_in_research&diff=59024Haskell in research2014-10-22T14:15:42Z<p>Tschrijvers: /* Research groups */</p>
<hr />
<div>Since its inception, Haskell development has been driven by programming<br />
language researchers. This page collects information about that community.<br />
<br />
==Research groups==<br />
<br />
*[http://www-i2.informatik.rwth-aachen.de/Forschung/FP/ Aachen]<br />
*[http://www-fp.cs.st-andrews.ac.uk/index.shtml St. Andrews]<br />
*[http://www.cs.bris.ac.uk/%7Eian/Functional/ Bristol]<br />
*[http://www.md.chalmers.se/Cs/Research/Functional/ Chalmers]<br />
*[http://www.ittc.ku.edu/research/view_lab.phtml?lab=CSDL Kansas]<br />
*[http://www.cs.kent.ac.uk/research/groups/tcs/fp/ Kent]<br />
*[http://people.cs.kuleuven.be/~tom.schrijvers/research.html Leuven]<br />
*[http://www.cs.mu.oz.au/fpu/ Melbourne]<br />
*[http://www.cse.unsw.edu.au/~pls/ New South Wales (Sydney)]<br />
*[http://www.cs.nott.ac.uk/Research/fop/ Nottingham]<br />
*[http://www.ogi.edu/csee/ OGI]<br />
*[http://metacomp.comlab.ox.ac.uk/projects Oxford]<br />
*[http://www.workingmouse.com/research/ Queensland (Brisbane)]<br />
*[http://www.cs.uu.nl/wiki/Center Utrecht]<br />
*[http://haskell.cs.yale.edu/yale/ Yale]<br />
*[http://www.cs.york.ac.uk/fp/ York]<br />
<br />
==Research positions==<br />
<br />
Advertise your research position on [[Jobs|the jobs page]].<br />
<br />
==Researchers==<br />
<br />
*[[Research_papers/Authors|Haskell people]]<br />
<br />
==Research papers==<br />
<br />
* A collection of [[Research papers|Haskell research]] papers.<br />
<br />
==Conferences==<br />
<br />
* A list of [[Conferences|conferences]] relevant to Haskell.<br />
<br />
===Haskell Symposium===<br />
<br />
*[http://haskell.org/haskell-symposium/2008/ The 2008 Haskell Symposium], Victoria, British Columbia, Canada.<br />
<br />
===Haskell Workshops===<br />
<br />
*[http://haskell.org/haskell-workshop/1995/ The First Haskell Workshop], 1995, La Jolla.<br />
*[http://www.haskell.org/haskell-workshop/1997/index.html The Second Haskell Workshop], 7 June 1997, Amsterdam, The Netherlands.<br />
*[http://www.haskell.org/HaskellWorkshop.html The Third Haskell Workshop], 1 October 1999, Paris, France.<br />
*[http://www.cs.nott.ac.uk/~gmh/hw00.html The Fourth Haskell Workshop], 17 September 2000, Montreal, Canada.<br />
*[http://haskell.org/haskell-workshop/2001/ The Fifth Haskell Workshop], September 2001, Firenze, Italy. <br />
*[http://www.cse.unsw.edu.au/~chak/hw2002/ The Sixth Haskell Workshop], October 2002, Pittsburgh, USA. <br />
*[http://www.haskell.org/haskell-workshop/2003/index.html The Seventh Haskell Workshop], August 2003, Uppsala, Sweden. <br />
*[http://www.cs.nott.ac.uk/~nhn/HW2004/ The Eigth Haskell Workshop], September 2004, Snowbird, Utah, USA.<br />
*[http://www.haskell.org/haskell-workshop/2005/ The Ninth Haskell Workshop], September 2005, Tallinn, Estonia.<br />
*[http://haskell.org/haskell-workshop/2006/ The Tenth Haskell Workshop], September 2006, Portland, Oregon, USA.<br />
*[http://haskell.org/haskell-workshop/2007/ The Eleventh Haskell Workshop], September 2007, Freiburg, Germany.<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Jobs&diff=59023Jobs2014-10-22T14:14:29Z<p>Tschrijvers: /* Academic positions */</p>
<hr />
<div>This page collects advertisements for commercial and academic positions involving Haskell or related technologies. <br />
<br />
If you are seeking Haskell jobs, or wish to recruit, good places to follow are the Haskell and Haskell-cafe mailing lists, the [http://cufp.org/jobs CUFP Job Opportunities list] and the Types mailing list (particularly for research jobs). Contacting those organisations listed on the [[Haskell in industry]] is a good idea. Joining the nascent networking site [http://www.haskellers.com Haskellers] may also prove beneficial.<br />
<br />
Please also supply the date when you add a new job opening to the list below.<br />
<br />
<br />
==Industry positions==<br />
<br />
*[http://www.bluespec.com/careers.html Bluespec, Inc.]<br />
*[http://www.checkpad.de/jobs factis research GmbH / Checkpad MED (German)]<br />
*[http://www.functor.se/careers/openings/ Functor AB]<br />
*[http://corp.galois.com/careers/ Galois, Inc]<br />
*[http://www.starling-software.com/en/employment/ Starling Software K.K.]<br />
*[http://www.tsurucapital.com/en/ Tsuru Capital LLC] <br />
<br />
===Related positions===<br />
<br />
* [https://www.erlang-solutions.com/about/careers Erlang Solutions]<br />
<br />
==Academic positions==<br />
<br />
* [http://people.cs.kuleuven.be/~tom.schrijvers/postdocposition2.html Postdoctoral position in Functional and Constraint Programming at KU Leuven] (added October, 2014)<br />
* [http://www3.imperial.ac.uk/computing/vacancies#JD0414 Research Assistant / Research Associate in Applied Computing] (added April 2014)<br />
* [http://cufp.org/jobs/programming-languages-researcher-haskell-expertise Programming Languages Researcher with Haskell Expertise] (added Sep 2010)<br />
<br />
==PhD/MSc Studentships==<br />
<br />
* [http://www.functor.se Industrial PhDs and MSc projects at Functor AB]<br />
<br />
==Internships==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/wiki/Internships Internships on Haskell and GHC, at Microsoft Research, Cambridge]<br />
* [http://www.haskellers.com/jobs/5 Spring Internship at Intel to develop EDSL for parallel vector computation] (added Nov 2010)<br />
<br />
<br />
==Job sites==<br />
<br />
* [http://www.haskellers.com/jobs Haskellers]<br />
* [http://cufp.org/jobs/language/31 Commercial Users of Functional Programming]<br />
* [http://functionaljobs.com/ Functional Jobs]<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Jobs&diff=59022Jobs2014-10-22T14:12:11Z<p>Tschrijvers: /* PhD/MSc Studentships */</p>
<hr />
<div>This page collects advertisements for commercial and academic positions involving Haskell or related technologies. <br />
<br />
If you are seeking Haskell jobs, or wish to recruit, good places to follow are the Haskell and Haskell-cafe mailing lists, the [http://cufp.org/jobs CUFP Job Opportunities list] and the Types mailing list (particularly for research jobs). Contacting those organisations listed on the [[Haskell in industry]] is a good idea. Joining the nascent networking site [http://www.haskellers.com Haskellers] may also prove beneficial.<br />
<br />
Please also supply the date when you add a new job opening to the list below.<br />
<br />
<br />
==Industry positions==<br />
<br />
*[http://www.bluespec.com/careers.html Bluespec, Inc.]<br />
*[http://www.checkpad.de/jobs factis research GmbH / Checkpad MED (German)]<br />
*[http://www.functor.se/careers/openings/ Functor AB]<br />
*[http://corp.galois.com/careers/ Galois, Inc]<br />
*[http://www.starling-software.com/en/employment/ Starling Software K.K.]<br />
*[http://www.tsurucapital.com/en/ Tsuru Capital LLC] <br />
<br />
===Related positions===<br />
<br />
* [https://www.erlang-solutions.com/about/careers Erlang Solutions]<br />
<br />
==Academic positions==<br />
<br />
* [http://tomschrijvers.blogspot.be/2014/09/postdoctoral-position-in-programming.html Postdoctoral position at KU Leuven] (deadline: October 15, 2014)<br />
* [http://www3.imperial.ac.uk/computing/vacancies#JD0414 Research Assistant / Research Associate in Applied Computing] (added April 2014)<br />
* [http://cufp.org/jobs/programming-languages-researcher-haskell-expertise Programming Languages Researcher with Haskell Expertise] (added Sep 2010)<br />
<br />
==PhD/MSc Studentships==<br />
<br />
* [http://www.functor.se Industrial PhDs and MSc projects at Functor AB]<br />
<br />
==Internships==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/wiki/Internships Internships on Haskell and GHC, at Microsoft Research, Cambridge]<br />
* [http://www.haskellers.com/jobs/5 Spring Internship at Intel to develop EDSL for parallel vector computation] (added Nov 2010)<br />
<br />
<br />
==Job sites==<br />
<br />
* [http://www.haskellers.com/jobs Haskellers]<br />
* [http://cufp.org/jobs/language/31 Commercial Users of Functional Programming]<br />
* [http://functionaljobs.com/ Functional Jobs]<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Jobs&diff=58855Jobs2014-09-22T15:37:02Z<p>Tschrijvers: /* Academic positions */</p>
<hr />
<div>This page collects advertisements for commercial and academic positions involving Haskell or related technologies. <br />
<br />
If you are seeking Haskell jobs, or wish to recruit, good places to follow are the Haskell and Haskell-cafe mailing lists, the [http://cufp.org/jobs CUFP Job Opportunities list] and the Types mailing list (particularly for research jobs). Contacting those organisations listed on the [[Haskell in industry]] is a good idea. Joining the nascent networking site [http://www.haskellers.com Haskellers] may also prove beneficial.<br />
<br />
Please also supply the date when you add a new job opening to the list below.<br />
<br />
<br />
==Industry positions==<br />
<br />
*[http://www.bluespec.com/careers.html Bluespec, Inc.]<br />
*[http://www.checkpad.de/jobs factis research GmbH / Checkpad MED (German)]<br />
*[http://www.functor.se/careers/openings/ Functor AB]<br />
*[http://corp.galois.com/careers/ Galois, Inc]<br />
*[http://www.starling-software.com/en/employment/ Starling Software K.K.]<br />
*[http://www.tsurucapital.com/en/ Tsuru Capital LLC] <br />
<br />
===Related positions===<br />
<br />
* [https://www.erlang-solutions.com/about/careers Erlang Solutions]<br />
<br />
==Academic positions==<br />
<br />
* [http://tomschrijvers.blogspot.be/2014/09/postdoctoral-position-in-programming.html Postdoctoral position at KU Leuven] (deadline: October 15, 2014)<br />
* [http://www3.imperial.ac.uk/computing/vacancies#JD0414 Research Assistant / Research Associate in Applied Computing] (added April 2014)<br />
* [http://cufp.org/jobs/programming-languages-researcher-haskell-expertise Programming Languages Researcher with Haskell Expertise] (added Sep 2010)<br />
<br />
==PhD/MSc Studentships==<br />
<br />
* [http://users.ugent.be/~tschrijv/phdposition3.html PhD studentship at Ghent University (posted on November 22, 2013)]<br />
* [http://www.functor.se Industrial PhDs and MSc projects at Functor AB]<br />
<br />
==Internships==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/wiki/Internships Internships on Haskell and GHC, at Microsoft Research, Cambridge]<br />
* [http://www.haskellers.com/jobs/5 Spring Internship at Intel to develop EDSL for parallel vector computation] (added Nov 2010)<br />
<br />
<br />
==Job sites==<br />
<br />
* [http://www.haskellers.com/jobs Haskellers]<br />
* [http://cufp.org/jobs/language/31 Commercial Users of Functional Programming]<br />
* [http://functionaljobs.com/ Functional Jobs]<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Jobs&diff=57131Jobs2013-11-22T12:36:38Z<p>Tschrijvers: /* PhD/MSc Studentships */</p>
<hr />
<div>This page collects advertisements for commercial and academic positions involving Haskell or related technologies. <br />
<br />
If you are seeking Haskell jobs, or wish to recruit, good places to follow are the Haskell and Haskell-cafe mailing lists, the [http://cufp.org/jobs CUFP Job Opportunities list] and the Types mailing list (particularly for research jobs). Contacting those organisations listed on the [[Haskell in industry]] is a good idea. Joining the nascent networking site [http://www.haskellers.com Haskellers] may also prove beneficial.<br />
<br />
Please also supply the date when you add a new job opening to the list below.<br />
<br />
<br />
==Industry positions==<br />
<br />
*[http://www.bluespec.com/about/careers.htm Bluespec, Inc.]<br />
*[http://www.functor.se/careers/openings/ Functor AB]<br />
*[http://corp.galois.com/careers/ Galois, Inc]<br />
*[http://www.starling-software.com/en/employment/ Starling Software K.K.]<br />
*[http://www.tsurucapital.com/en/ Tsuru Capital LLC] <br />
<br />
===Related positions===<br />
<br />
* [https://www.erlang-solutions.com/about/careers Erlang Solutions]<br />
<br />
==Academic positions==<br />
<br />
* [http://cufp.org/jobs/programming-languages-researcher-haskell-expertise Programming Languages Researcher with Haskell Expertise] (added Sep 2010)<br />
<br />
<br />
==PhD/MSc Studentships==<br />
<br />
* [http://users.ugent.be/~tschrijv/phdposition3.html PhD studentship at Ghent University (posted on November 22, 2013)]<br />
* [http://www.functor.se Industrial PhDs and MSc projects at Functor AB]<br />
<br />
==Internships==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/wiki/Internships Internships on Haskell and GHC, at Microsoft Research, Cambridge]<br />
* [http://www.haskellers.com/jobs/5 Spring Internship at Intel to develop EDSL for parallel vector computation] (added Nov 2010)<br />
<br />
<br />
==Job sites==<br />
<br />
* [http://www.haskellers.com/jobs Haskellers]<br />
* [http://cufp.org/jobs/language/31 Commercial Users of Functional Programming]<br />
* [http://functionaljobs.com/ Functional Jobs]<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Jobs&diff=43630Jobs2011-12-16T16:02:47Z<p>Tschrijvers: /* PhD/MSc Studentships */</p>
<hr />
<div>This page collects advertisements for commercial and academic positions involving Haskell or related technologies. <br />
<br />
If you are seeking Haskell jobs, or wish to recruit, good places to follow are the Haskell and Haskell-cafe mailing lists, the [http://cufp.org/jobs CUFP Job Opportunities list] and the Types mailing list (particularly for research jobs). Contacting those organisations listed on the [[Haskell in industry]] is a good idea. Joining the nascent networking site [http://haskellers.com Haskellers] may also prove beneficial.<br />
<br />
Please also supply the date when you add a new job opening to the list below.<br />
<br />
==Industry positions==<br />
<br />
*[http://www.aetion.com/ Aetion Technologies LLC]<br />
*[http://www.bluespec.com/about/careers.htm Bluespec, Inc.]<br />
*[http://www.galois.com/company/careers Galois, Inc]<br />
*[http://www.starling-software.com/en/employment/ Starling Software K.K.]<br />
*[http://www.tsurucapital.com/en/ Tsuru Capital LLC] <br />
<br />
===Related positions===<br />
* [http://www.erlang-solutions.com/jobs/ Erlang Solutions]<br />
* [http://www.simcorp.com/Home/Careers/Jobs/Denmark.aspx SimCorp is looking for Ocaml Software Developers]<br />
<br />
==Academic positions==<br />
* [http://cufp.org/jobs/programming-languages-researcher-haskell-expertise] Programming Languages Researcher with Haskell Expertise (added Sep 2010)<br />
<br />
==PhD/MSc Studentships==<br />
<br />
* [http://users.ugent.be/~tschrijv/phdposition2.html PhD studentship at Ghent University] <br />
* PhD studentships in Nottingham (deadline 1st March 2011) [http://www.cs.nott.ac.uk/~gmh/phd-advert.txt]<br />
<br />
==Internships==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/wiki/Internships Internships on Haskell and GHC, at Microsoft Research, Cambridge]<br />
* [http://www.haskellers.com/jobs/5/ Spring Internship at Intel to develop EDSL for parallel vector computation] (added Nov 2010)<br />
<br />
<br />
==Job sites==<br />
<br />
* [http://www.haskellers.com/jobs/ Haskellers]<br />
* [http://cufp.org/jobs/language/31 Commercial Users of Functional Programming]<br />
* [http://functionaljobs.com/ Functional Jobs]<br />
<br />
[[Category:Community]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Conferences&diff=41683Conferences2011-08-19T08:18:46Z<p>Tschrijvers: /* International Symposium on Functional and Logic Programming (FLOPS) */</p>
<hr />
<div>Haskell programmers publish a great deal of [[Research papers|research]]<br />
at conferences, which are also great places to meet and discuss <br />
Haskell and its future. The following is a list of some of the<br />
conferences at which Haskellers and their research appears.<br />
<br />
For a calendar-like interface, see [http://www.unsafeperformio.com/confs.php Andy Gill's page].<br />
<br />
== The Haskell Symposium ==<br />
<br />
* [http://haskell.org/haskell-symposium/ The Haskell Symposium].<br />
<br />
The Haskell Symposium is an annual symposium organized in affiliation with<br />
the International Conference on Functional Programming (ICFP). The<br />
workshop is sponsored by the Association for Computing Machinery (ACM)<br />
under the aegis of the ACM Special Interest Group on Programming<br />
Languages (SIGPLAN).<br />
<br />
The purpose of the Haskell Symposium is to discuss experience with<br />
Haskell, and future developments for the language. The scope of the<br />
symposium includes all aspects of the design, semantics, theory,<br />
application, implementation, and teaching of Haskell.<br />
<br />
== The International Conference on Functional Programming (ICFP) ==<br />
<br />
* [http://www.cs.luc.edu/icfp/ The International Conference on Functional Programming (ICFP)]<br />
<br />
ICFP (International Conference on Functional Programming) is an annual<br />
programming language conference. It is sponsored by the Association for<br />
Computing Machinery under the aegis of the ACM Special Interest Group on<br />
Programming Languages (SIGPLAN), in association with Working Group 2.8<br />
of the International Federation of Information Processing (IFIP).<br />
<br />
== Commercial Users of Functional Programming (CUFP) ==<br />
<br />
* [http://www.galois.com/cufp/ Commercial Users of Functional Programming Workshop]<br />
<br />
The goal of CUFP is to build a community for users of functional<br />
programming languages and technology, be they using functional languages<br />
in their professional lives, in an open source project (other than<br />
implementation of functional languages), as a hobby, or any combination<br />
thereof. In short: anyone who uses functional programming as a means,<br />
but not an end<br />
<br />
== International Symposium on Functional and Logic Programming (FLOPS) ==<br />
<br />
* [http://www.org.kobe-u.ac.jp/flops2012/ FLOPS 2012]<br />
<br />
FLOPS is a forum for research on all issues concerning declarative programming, including functional programming and logic programming, and aims to promote cross-fertilization and integration between the two paradigms.<br />
<br />
== Principles of Programming Languages (POPL) ==<br />
<br />
* [http://www.cs.ucsd.edu/popl/07/ Principles of Programming Languages (POPL)]<br />
<br />
== Programming Language Design and Implementation (PLDI) ==<br />
<br />
* [http://research.microsoft.com/conferences/pldi06/ Programming Language Design and Implementation (PLDI)]<br />
<br />
== Implementation of Functional Languages (IFL) ==<br />
<br />
* [http://plc.inf.elte.hu/ifl2006/ Implementation of Functional Languages (IFL)]<br />
<br />
== Practical Aspects of Declarative Languages (PADL) ==<br />
<br />
* [http://www.informatik.uni-kiel.de/~mh/padl07 Practical Applications of Declarative Languages (PADL)]<br />
<br />
== Principles and Practice of Declarative Programming (PPDP) ==<br />
<br />
* [http://www.risc.jku.at/about/conferences/ppdp2010/ Principles and Practice of Declarative Programming (PPDP)]<br />
<br />
== Asian Symposium on Programming Languages and Systems (APLAS) ==<br />
<br />
* [http://www.kb.ecei.tohoku.ac.jp/aplas2006/ Asian Symposium on Programming Languages and Systems (APLAS]<br />
<br />
== Declarative Aspects of Multicore Programming (DAMP) ==<br />
<br />
* [http://www.cs.cmu.edu/~damp Declarative Aspects of Multicore Programming (DAMP)]<br />
<br />
== Types in Language Design and Implementation (TLDI) ==<br />
<br />
* [http://www.cs.berkeley.edu/%7Enecula/tldi07/ Types in Language Design and Implementation (TLDI)]<br />
<br />
== Trends in Functional Programming (TFP) ==<br />
<br />
* [http://www.tifp.org/ Trends in Functional Programming]<br />
<br />
== Principles, Logics, and Implementations of High-Level Programming Languages (PLI) ==<br />
<br />
* [http://pli2002.cs.brown.edu/ PLI]<br />
<br />
== Types in Compilation Workshop (TIC) ==<br />
<br />
* [http://www.cs.cmu.edu/~crary/tic00/ Types in Compilation (TIC)]<br />
<br />
== Practical Aspects of High-level Parallel Programming (PAPP) ==<br />
<br />
* [http://f.loulergue.free.fr/PAPP2007/index.html Practical Aspects of High-level Parallel Programming]<br />
<br />
== Federated Conference on Rewriting, Deduction, and Programming (RDP) ==<br />
<br />
* [http://www.lsv.ens-cachan.fr/rdp07/ Federated Conference on Rewriting, Deduction, and Programming]<br />
<br />
== Typed Lambda Calculi and Applications (TLCA) ==<br />
<br />
* [http://www.lsv.ens-cachan.fr/rdp07/tlca.html Typed Lambda Calculi and Applications (TLCA '07)]<br />
<br />
== International Workshop on Functional and Declarative Programming in Education ==<br />
<br />
* [http://www.informatik.uni-kiel.de/~mh/publications/reports/fdpe02/ FDPE]<br />
<br />
== Advanced Functional Programming Spring School (AFP) ==<br />
<br />
* [http://www.cs.ut.ee/afp04/ Advanced Functional Programming: 5th International School]<br />
<br />
== Integrated Formal Methods (IFM) ==<br />
<br />
* [http://www.softeng.ox.ac.uk/ifm2007/ Integrated Formal Methods 2007]<br />
<br />
== UTP'07 at IFM: Unifying Theories of Programming ==<br />
<br />
* [http://www.ifm2007.org Unifying Theories of Programming]<br />
<br />
== Systems Software Verification (SSV) ==<br />
<br />
* [http://nicta.com.au/ssv08/ Systems Software Verification Workshop]<br />
<br />
Please add more Haskell-related conferences as they appear.<br />
<br />
<br />
<br />
[[Category:Events]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Conferences&diff=41682Conferences2011-08-19T08:18:21Z<p>Tschrijvers: added FLOPS</p>
<hr />
<div>Haskell programmers publish a great deal of [[Research papers|research]]<br />
at conferences, which are also great places to meet and discuss <br />
Haskell and its future. The following is a list of some of the<br />
conferences at which Haskellers and their research appears.<br />
<br />
For a calendar-like interface, see [http://www.unsafeperformio.com/confs.php Andy Gill's page].<br />
<br />
== The Haskell Symposium ==<br />
<br />
* [http://haskell.org/haskell-symposium/ The Haskell Symposium].<br />
<br />
The Haskell Symposium is an annual symposium organized in affiliation with<br />
the International Conference on Functional Programming (ICFP). The<br />
workshop is sponsored by the Association for Computing Machinery (ACM)<br />
under the aegis of the ACM Special Interest Group on Programming<br />
Languages (SIGPLAN).<br />
<br />
The purpose of the Haskell Symposium is to discuss experience with<br />
Haskell, and future developments for the language. The scope of the<br />
symposium includes all aspects of the design, semantics, theory,<br />
application, implementation, and teaching of Haskell.<br />
<br />
== The International Conference on Functional Programming (ICFP) ==<br />
<br />
* [http://www.cs.luc.edu/icfp/ The International Conference on Functional Programming (ICFP)]<br />
<br />
ICFP (International Conference on Functional Programming) is an annual<br />
programming language conference. It is sponsored by the Association for<br />
Computing Machinery under the aegis of the ACM Special Interest Group on<br />
Programming Languages (SIGPLAN), in association with Working Group 2.8<br />
of the International Federation of Information Processing (IFIP).<br />
<br />
== Commercial Users of Functional Programming (CUFP) ==<br />
<br />
* [http://www.galois.com/cufp/ Commercial Users of Functional Programming Workshop]<br />
<br />
The goal of CUFP is to build a community for users of functional<br />
programming languages and technology, be they using functional languages<br />
in their professional lives, in an open source project (other than<br />
implementation of functional languages), as a hobby, or any combination<br />
thereof. In short: anyone who uses functional programming as a means,<br />
but not an end<br />
<br />
== International Symposium on Functional and Logic Programming (FLOPS) ==<br />
<br />
* [http://www.org.kobe-u.ac.jp/flops2012/]<br />
<br />
FLOPS is a forum for research on all issues concerning declarative programming, including functional programming and logic programming, and aims to promote cross-fertilization and integration between the two paradigms.<br />
<br />
== Principles of Programming Languages (POPL) ==<br />
<br />
* [http://www.cs.ucsd.edu/popl/07/ Principles of Programming Languages (POPL)]<br />
<br />
== Programming Language Design and Implementation (PLDI) ==<br />
<br />
* [http://research.microsoft.com/conferences/pldi06/ Programming Language Design and Implementation (PLDI)]<br />
<br />
== Implementation of Functional Languages (IFL) ==<br />
<br />
* [http://plc.inf.elte.hu/ifl2006/ Implementation of Functional Languages (IFL)]<br />
<br />
== Practical Aspects of Declarative Languages (PADL) ==<br />
<br />
* [http://www.informatik.uni-kiel.de/~mh/padl07 Practical Applications of Declarative Languages (PADL)]<br />
<br />
== Principles and Practice of Declarative Programming (PPDP) ==<br />
<br />
* [http://www.risc.jku.at/about/conferences/ppdp2010/ Principles and Practice of Declarative Programming (PPDP)]<br />
<br />
== Asian Symposium on Programming Languages and Systems (APLAS) ==<br />
<br />
* [http://www.kb.ecei.tohoku.ac.jp/aplas2006/ Asian Symposium on Programming Languages and Systems (APLAS]<br />
<br />
== Declarative Aspects of Multicore Programming (DAMP) ==<br />
<br />
* [http://www.cs.cmu.edu/~damp Declarative Aspects of Multicore Programming (DAMP)]<br />
<br />
== Types in Language Design and Implementation (TLDI) ==<br />
<br />
* [http://www.cs.berkeley.edu/%7Enecula/tldi07/ Types in Language Design and Implementation (TLDI)]<br />
<br />
== Trends in Functional Programming (TFP) ==<br />
<br />
* [http://www.tifp.org/ Trends in Functional Programming]<br />
<br />
== Principles, Logics, and Implementations of High-Level Programming Languages (PLI) ==<br />
<br />
* [http://pli2002.cs.brown.edu/ PLI]<br />
<br />
== Types in Compilation Workshop (TIC) ==<br />
<br />
* [http://www.cs.cmu.edu/~crary/tic00/ Types in Compilation (TIC)]<br />
<br />
== Practical Aspects of High-level Parallel Programming (PAPP) ==<br />
<br />
* [http://f.loulergue.free.fr/PAPP2007/index.html Practical Aspects of High-level Parallel Programming]<br />
<br />
== Federated Conference on Rewriting, Deduction, and Programming (RDP) ==<br />
<br />
* [http://www.lsv.ens-cachan.fr/rdp07/ Federated Conference on Rewriting, Deduction, and Programming]<br />
<br />
== Typed Lambda Calculi and Applications (TLCA) ==<br />
<br />
* [http://www.lsv.ens-cachan.fr/rdp07/tlca.html Typed Lambda Calculi and Applications (TLCA '07)]<br />
<br />
== International Workshop on Functional and Declarative Programming in Education ==<br />
<br />
* [http://www.informatik.uni-kiel.de/~mh/publications/reports/fdpe02/ FDPE]<br />
<br />
== Advanced Functional Programming Spring School (AFP) ==<br />
<br />
* [http://www.cs.ut.ee/afp04/ Advanced Functional Programming: 5th International School]<br />
<br />
== Integrated Formal Methods (IFM) ==<br />
<br />
* [http://www.softeng.ox.ac.uk/ifm2007/ Integrated Formal Methods 2007]<br />
<br />
== UTP'07 at IFM: Unifying Theories of Programming ==<br />
<br />
* [http://www.ifm2007.org Unifying Theories of Programming]<br />
<br />
== Systems Software Verification (SSV) ==<br />
<br />
* [http://nicta.com.au/ssv08/ Systems Software Verification Workshop]<br />
<br />
Please add more Haskell-related conferences as they appear.<br />
<br />
<br />
<br />
[[Category:Events]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Domain_specific_languages&diff=30297Research papers/Domain specific languages2009-09-27T18:00:54Z<p>Tschrijvers: added Monadic Constraint Programming paper</p>
<hr />
<div>__TOC__<br />
<br />
==Domain specific languages==<br />
<br />
;[http://legacy.cs.uu.nl/daan/download/papers/dsec.ps Domain Specific Embedded Compilers]<br />
:Daan Leijen and Erik Meijer. 2nd USENIX Conference on Domain-Specific Languages (DSL'99), Austin, Texas, October 1999. Also appeared in ACM SIGPLAN Notices 35, 1, January 2000.<br />
<br />
;[http://conal.net/papers/jfp-saig/ Compiling Embedded Languages]<br />
:Conal Elliott, Sigbjorn Finne, Oege de Moor. Journal of Functional Programming, 13(2), 2003.<br />
<br />
;[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.5061 Modular Domain Specific Languages and Tools]<br />
:Hudak (1998) (cited by 92)<br />
<br />
;[https://eprints.kfupm.edu.sa/28924/ Building Domain-Specific Embedded Languages] ([http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.49.6020 citeseer link])<br />
:Paul Hudak (cited by 102)<br />
<br />
;[http://www.usenix.org/publications/library/proceedings/dsl99/full_papers/leijen/leijen.ps Domain Specific Embedded Compilers] <br />
:D Leijen, E Meijer (cited by 88)<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fid%3D317765.317794 Haskell and XML: generic combinators or type-based translation?]<br />
:M Wallace, C Runciman - ACM SIGPLAN Notices, 1999 <br />
<br />
;[http://www.springerlink.com/index/RPRWGR7LHTXBT2DW.pdf Modeling HTML in Haskell]<br />
:P Thiemann - Practical Applications of Declarative Languages, 2000 (cited by 24)<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D331975 DSL implementation using staging and monads]<br />
:T Sheard, E Pasalic - Proceedings of the 2nd conference on Domain-specific languages, 1999<br />
<br />
;[http://www.informatik.uni-freiburg.de/~thiemann/papers/wflp02.ps.gz Programmable type systems for domain specific languages]<br />
:P Thiemann Electronic Notes in Theoretical Computer Science, 2002<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fid%3D1052935 An embedded domain-specific language for type-safe server-side web scripting]<br />
:P Thiemann, ACM Transactions on Internet Technology (TOIT), 2005<br />
<br />
;[http://www.informatik.uni-freiburg.de/~thiemann/papers/modeling.ps.gz A typed representation for HTML and XML documents in Haskell]<br />
:P Thiemann, Journal of Functional Programming, 2003 (cited by 38)<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fid%3D331963.331976 Monadic robotics]<br />
:J Peterson, G Hager.<br />
<br />
;[ftp://cse.ogi.edu/pub/pacsoft/papers/dsl-tools.ps Defining and Implementing Closed, Domain-Specific Languages]<br />
:RB Kieburtz - Invited talk, 2000 <br />
<br />
===Rapid prototyping===<br />
<br />
;[http://www.haskell.org/frob/icse99/visionpaper.ps Prototyping Real-Time Vision Systems: An Experiment in DSL Design]<br />
:A. Reid, J. Peterson, G. Hager and P. Hudak, In Proceedings of International Conference on Software Engineering (ICSE'99), Los Angeles, CA. 16-22 May, 1999.<br />
<br />
;[http://www.haskell.org/yale/papers/padl01-vision/index.html FVision: A Declarative Language for Visual Tracking]<br />
:J. Peterson, P. Hudak, A. Reid and G. Hager. In Proceedings of Third International Symposium on Practical Applications of Declarative Languages PADL'01, March 2001.<br />
<br />
===Graphics===<br />
<br />
;[https://www.usenix.org/publications/library/proceedings/dsl97/full_papers/elliott/elliott.pdf Modeling Interactive 3D and Multimedia Animation with an Embedded Language]<br />
:Conal Elliott (cited by 35)<br />
<br />
;[http://conal.net/papers/Vertigo/ Programming Graphics Processors Functionally]<br />
:Conal Elliott. Proceedings of the 2004 Haskell Workshop.<br />
<br />
;[http://conal.net/papers/functional-images/ Functional Images]<br />
:Conal Elliott. In The Fun of Programming, March 2003.<br />
<br />
;[http://conal.net/papers/Eros/ Tangible Functional Programming]<br />
:Conal Elliott, ICFP 07<br />
<br />
===Hardware design===<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/charme01-sorter.pdf The Design and Verification of a Sorter Core]<br />
:Koen Claessen, Mary Sheeran, and Satnam Singh. In Proc. of Conference on Correct Hardware Design and Verification Methods (CHARME), Lecture Notes in Computer Science, Springer Verlag, 2001.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/lic.ps An Embedded Language Approach to Hardware Description and Verification]<br />
:Koen Claessen. Dept. of Computer Science and Engineering, Chalmers University of Technology, Lic. thesis, August 2000.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/phd01-thesis.ps Embedded Languages for Describing and Verifying Hardware]<br />
:Koen Claessen. Dept. of Computer Science and Engineering, Chalmers University of Technology, Ph.D. thesis, April 2001.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/fdpe02-lava.ps An Embedded Language Approach to Teaching Hardware Compilation]<br />
:Koen Claessen and Gordon Pace. In Proc. of Workshop on Functional and Declarative Programming in Education (FDPE), 2002.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/constructive.ps Safety Property Verification of Cyclic Circuits]<br />
:Koen Claessen. June 2002.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/paps.ps Verification of Hardware Systems with First-Order Logic]<br />
:Koen Claessen, Reiner Hähnle, Johan Mårtensson. PaPS 2002. 2002.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/dcc-hwcomp.ps An Embedded Language Framework for Hardware Compilation]<br />
:Koen Claessen, Gordon Pace. DCC 2002. 2002.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/obs-shar.ps Observable Sharing for Functional Circuit Description]<br />
:Koen Claessen and David Sands. ASIAN '99. 1999.<br />
<br />
;[http://www.cs.chalmers.se/~bjesse/fftpaper.ps.gz Automatic Verification of Combinational and Pipelined FFT Circuits]<br />
:Per Bjesse. CAV. 1999<br />
<br />
;[http://content.ohsu.edu/cdm4/item_viewer.php?CISOROOT=/etd&CISOPTR=212&CISOBOX=1&REC=9 Algebraic Specification and Verification of Processor Microarchitectures]<br />
:John Matthews. PhD. Thesis. Oregon Graduate Institute. 2000.<br />
<br />
;[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.26.8326 Symbolic Simulation of Microprocessor Models using Type Classes in Haskell]<br />
:Nancy A. Day, Jeffrey R. Lewis and Byron Cook. CHARME'99. September 1999.<br />
<br />
;[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.4284 On Embedding a Microarchitectural Design Language within Haskell]<br />
:John Launchbury, Jeff Lewis and Byron Cook. ICFP'99. 1999. <br />
<br />
;[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.5519 Elementary Microarchitecture Algebra]<br />
:John Matthews and John Launchbury. CAV '99. 1999.<br />
<br />
;[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.1486 Specifying Superscalar Microprocessors with Hawk]<br />
:Byron Cook, John Launchbury and John Matthews. FTH '98. 1998.<br />
<br />
;[https://wiki.ittc.ku.edu/lambda/Image:Matthews-Microprocessor_Specification_in_HAWK.pdf Microprocessor Specification in Hawk]<br />
:John Matthews, John Launchbury and Byron Cook. ICCL '98. 1998.<br />
<br />
====Lava====<br />
<br />
;[http://www.cs.chalmers.se/~koen/Papers/lava.ps Lava: Hardware Design in Haskell]<br />
:Per Bjesse, Koen Claessen, Mary Sheeran, Satnam Singh<br />
<br />
;[http://www.math.chalmers.se/~koen/pubs/entry-sttt03-lava.html Using Lava to Design and Verify Recursive and Periodic Sorters]<br />
:Koen Claessen, Mary Sheeran, and Satnam Singh. In International Journal on Software Tools for Technology Transfer, vol. 4 (3), pp. 349--358, Springer Verlag, 2003.<br />
<br />
;[http://www.math.chalmers.se/~koen/pubs/entry-fop-lava.html Functional Hardware Description in Lava]<br />
:Koen Claessen, Mary Sheeran, and Satnam Singh. In Jeremy Gibbons and Oege de Moor (eds.), The Fun of Programming, Cornerstones of Computing, pp. 151--176, Palgrave, 2003.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Lava/tutorial.ps A Lava Tutorial]<br />
:Koen Claessen, Mary Sheeran. April 2000.<br />
<br />
===Network programming===<br />
<br />
;[http://www.fujipress.jp/finder/xslt.php?mode=present&inputfile=IPSTP004700160002.xml A Network Programming Framework in Haskell Based on Asynchronous Localized pi-calculus]<br />
:Keigo Imai ,Shoji Yuen ,Kiyoshi Agusa. Graduate School of Information Science, Nagoya University Journal ref: IPSJ Transactions on Programming, Vol.47, No.16 pp. 10-28, 2006<br />
<br />
===Logic and constraint programming===<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/haskell00-typedlp.ps Typed Logical Variables in Haskell]<br />
:Koen Claessen and Peter Ljunglöf. In Proc. of Haskell Workshop, ACM SIGPLAN, 2000. 1999<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/Prolog.ps.gz Prolog's control constructs in a functional setting - Axioms and implementation]<br />
:Ralf Hinze. International Journal of Foundations of Computer Science. 12 (2). 2001.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/modref2009.pdf Monadic Constraint Programming]<br />
:Tom Schrijvers, Peter Stuckey and Phil Wadler. Journal of Functional Programming, 2009.<br />
<br />
[[Category:Research]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=AngloHaskell/2009&diff=28468AngloHaskell/20092009-06-03T08:30:29Z<p>Tschrijvers: </p>
<hr />
<div>AngloHaskell 2009 is taking place on the 7th of August at MSR Cambridge, with further activities on the 8th. It's free, and everyone is invited! Simply add your name to the wiki and we'll see you there :-)<br />
<br />
We could use local contacts and someone to act as organisational contact on the day. People willing to put someone up for the night (even if on a floor) would also be much appreciated. Any volunteers?<br />
<br />
== Date and Venue ==<br />
<br />
7th-8th of August in Cambridge, UK, starting with talks at Microsoft Research and with more planning to happen below.<br />
<br />
=== Directions to MSR ===<br />
<br />
MSR has [http://research.microsoft.com/aboutmsr/visitmsr/cambridge/directions.aspx some directions], which can be best summarised as ‘get a taxi’. Here is (hopefully) a [http://earth.google.com/ Google Earth] [[Media:Microsoft_Research,_Cambridge.kmz|location]] of MSR, as well as a [http://maps.google.com/maps?q=CB3+0FB&ll=52.211499,0.117073&spn=0.02677,0.086517 Google Maps link]. (J J Thomson Avenue is immediately west of Clerk Maxwell Road.)<br />
<br />
If you do take a taxi and the driver doesn't know where it is, tell him or her to drive down Madingley Road until you reach the West Cambridge site, J J Thomson Avenue. The Computer Laboratory (next door) has [http://www.cl.cam.ac.uk/UoCCL/contacts/#gettinghere marginally better instructions].<br />
<br />
The fastest way to MSR (on foot and public transport) from the station is to [http://maps.google.com/maps?saddr=CB1+2JW&daddr=Trumpington+Road,+Cambridge cut through to Trumpington Road via Bateman Street] (don't follow the driving directions!), and take the Citi 4 or Uni 4. There's a bus stop just across the road from Bateman Street.<br />
<br />
To get to the city centre by bus, take the Citi 1 or Citi 3. Do ask to make sure they're going in the right direction though! There are also a number of clearly marked shuttle busses between the centre and station running during the day every 10 minutes or so.<br />
<br />
To walk to the centre (20 minutes not carrying luggage), go straight down the road facing you when you come out of the station, bear right when the road ends at some traffic lights / a WW1 memorial / the botanic gardens, and keep walking straight (Hills Road / Regent St / St Andrews St) for quite a while until you reach a pedestrianised bit, at which point you are in the centre.<br />
<br />
From the city centre to MSR, you can catch the number 77 Madingley Road Park and Ride which goes from bus stop M on Emma St. (Or find your way to Pembroke or Silver Street, and catch the Citi 4 / Uni 4 from there.) (Note that the 77 doesn't stop by MSR any more, it goes to the park and ride from which you have to walk back, 10-15 mins. This caught me out the other day --SimonM).<br />
<br />
==== Parking ====<br />
<br />
To be verified:<br />
<br />
Some parking spaces will be available around the back of the MSR building. To get out again, drivers will need to talk to reception to obtain a token.<br />
<br />
== Attendees ==<br />
<br />
Per last year, all attendees should '''bring or make a nametag''' that identifies you by your real name and/or IRC name. If anyone wants to drag a roll of stickers and a pen along that'll help!<br />
<br />
If you can't make the start on Friday, or can only make it on Saturday, that's fine. If you're not sure where everyone's going to be, give one of the contacts a call or a text.<br />
<br />
=== Definite ===<br />
<br />
* Philippa Cowderoy<br />
* Neil Mitchell<br />
* Eric Kow<br />
* Tom Schrijvers<br />
<br />
=== Possible ===<br />
<br />
== Lodging ==<br />
<br />
It's likely that there'll be people in need of crashspace and so forth, so please organise here! Both offers and requests are good.<br />
<br />
=== Nearby Colleges ===<br />
<br />
Many of undergraduate colleges (which are really glorified halls of residence) offer cheap accommodation over the holidays. Locations near MSR include Churchill College, Wolfson Court (an annexe of Girton College), Fitzwillian College, Robinson College, New Hall (female only) and Burwells Field (an annexe of Trinity College).<br />
<br />
[http://www.cam.ac.uk/map/v4/drawmap.cgi?mp=main;xx=900;yy=560;mt=c;mx=759;my=467;ms=75;tl=Microsoft%20Research This map] might prove useful.<br />
<br />
-- [http://www.dysfunctor.org/ Peter McArthur]<br />
<br />
=== Hostels ===<br />
<br />
There's a fairly inexpensive [http://www.yha.org.uk/find-accommodation/east-of-england/hostels/cambridge/index.aspx YHA hostel] in Cambridge. There may be others.<br />
<br />
Another guest house right next to the station is Tenison Towers (01223 363924).<br />
<br />
== Programme ==<br />
<br />
Planning will be taking place on IRC as per previous years: #anglohaskell on irc.freenode.net<br />
<br />
If you're having trouble following things on IRC, the discussion page on the wiki might be a good place to leave comments and questions.<br />
<br />
Previous years in Cambridge we had talks in the day on a Friday, followed by pubbage in the evening and assorted activities on the Saturday. This seemed to work, so we'll follow a similar model this year. Sadly we can't have talk space at MSR on a Saturday.<br />
<br />
=== Talks ===<br />
<br />
Volunteers please! Previously we have had a largely more practical set of talks than you might find at Fun in the Afternoon or an academic event. This was a good thing, and some of the best talks were from people who were far from considering themselves as experts, so feel free to tell us about your experiences.<br />
<br />
In the event that more talks are offered than we have time for at MSR, we'll have to work out what we can do to find more time.<br />
<br />
Talks planned and/or offered:<br />
<br />
* Neil Mitchell - hopefully "Make Considered Harmful"<br />
* Tom Schrijvers - "Monadic Constraint Programming"<br />
<br />
==== Abstracts ====<br />
<br />
People giving talks should add these as they have them :-)<br />
<br />
* Monadic Constraint Programming<br />
<br />
A constraint programming system combines two essential components: a constraint solver and a search engine. The constraint solver reasons about satisfiability of conjunctions of constraints, and the search engine controls the search for solutions by iteratively exploring a disjunctive search tree defined by the constraint program.<br />
<br />
The Monadic Constraint Programming framework gives a monadic definition of constraint programming where the solver is defined as a monad threaded through the monadic search tree. Search and search strategies can then be defined as firstclass objects that can themselves be built or extended by composable search transformers. Search transformers give a powerful and unifying approach to viewing search in constraint programming, and the resulting constraint programming system is first class and extremely flexible. <br />
<br />
=== Other activity ===<br />
<br />
After Friday's talks, food and drink would be a good idea! Curry is traditional and probably the default, but we're open to other suggestions. After that, we'll retreat to a pub for the evening.<br />
<br />
Repeating previous years, I suggest we go to [http://www.beerintheevening.com/pubs/s/13/1361/Regal/Cambridge The Regal] for brunch on Saturday to kick off with. That's the Wetherspoons from last year. After that, punting again if it's not raining too much? Any suggestions for if it's wet?<br />
<br />
[[User:PhilippaCowderoy|PhilippaCowderoy]]<br />
<br />
[[Category:Events]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Type_systems&diff=28213Research papers/Type systems2009-05-15T11:18:34Z<p>Tschrijvers: </p>
<hr />
<div>__TOC__<br />
<br />
==Haskell semantics==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/static-semantics.dvi.gz A static semantics for Haskell]<br />
:SL Peyton Jones and PL Wadler, (draft), Department of Computing Science, University of Glasgow, 1992. (Cited by 20)<br />
<br />
;[http://haskell.org/onlinereport/dynamic-semantics.dvi.gz A Dynamic Semantics for Haskell] <br />
:Kevin Hammond and Cordelia Hall, (draft), University of Glasgow, 1992, 23 pages.<br />
<br />
;[http://citeseer.ist.psu.edu/424440.html Typing Haskell in Haskell] <br />
:Mark P. Jones, In Proceedings of the 1999 Haskell Workshop, Paris, France, October 1999. Published in Technical Report UU-CS-1999-28, Department of Computer Science, University of Utrecht. (Cited by 66)<br />
<br />
;[http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne/haskell_libs/hsparser.html HParser]<br />
:A parser for Haskell written purely in Haskell (using the Happy parser generator).<br />
<br />
;[http://www.cse.ogi.edu/~hallgren/Talks/LHiH/ A Lexer for Haskell in Haskell]<br />
:Thomas Hallgren, PacSoft Oregon Graduate Institute, 14 January, 2002<br />
<br />
;[http://citeseer.ist.psu.edu/launchbury93natural.html A Natural Semantics for Lazy Evaluation]<br />
:John Launchbury, Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, 144--154, 1993.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/papers/11.ps A Space Semantics for Core Haskell]<br />
:Adam Bakewell. Proc. 2000 Haskell Workshop. September 2001.<br />
<br />
==Pure type systems==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/henk.ps.gz Henk: a typed intermediate language]<br />
:SL Peyton Jones and E Meijer, Proceedings of the Types in Compilation Workshop, Amsterdam, June 1997.<br />
<br />
;[http://www.cs.uu.nl/~johanj/MSc/jwroorda/ Pure Type Systems for Functional Programming]<br />
:Jan-Willem Roorda, Masters Thesis, University of Utrecht, INF/SCR-00-13, available online, 2000<br />
<br />
==Dependent Types==<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/ydtm.pdf Why Dependent Types Matter]<br />
:Thorsten Altenkirch and Conor McBride and James McKinna, Manuscript, available online, April, 2005. (Cited by 7)<br />
<br />
;[http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html Simply Easy! An Implementation of a Dependently Typed Lambda Calculus]<br />
:Andres Löh, Conor McBride and Wouter Swierstra, 2007.<br />
<br />
==Unboxed values==<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z Unboxed values as first class citizens]<br />
:SL Peyton Jones and J Launchbury, Functional Programming Languages and Computer Architecture (FPCA'91), Boston, LNCS 523, Springer Verlag, Sept 1991, pp636-666. (Cited by 105)<br />
<br />
==Modules==<br />
<br />
;[http://www.cse.ogi.edu/~diatchki/papers/modules98.pdf A Formal Specification of the Haskell 98 Module System]<br />
:Iavor S. Diatchki, Mark P. Jones, and Thomas Hallgren. Proceedings of the 2002 ACM SIGPLAN workshop on Haskell. Pittsburgh, Pennsylvania. 17 - 28 2002 ISBN 1-58113-605-6 (Cited by 12)<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/first-class-modules/index.htm First class modules for Haskell]<br />
:Mark Shields and Simon Peyton Jones; FOOL'02.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/Nicklisch-modules.ps.gz An exploration of modular programs]<br />
:Electronic proceedings of the 1996 Glasgow Functional Programming Workshop, J Nicklisch and SL Peyton Jones, Ullapool, July 1996.<br />
<br />
==Exceptions==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf An Extensible Dynamically-Typed Hierarchy of Exceptions]<br />
:Simon Marlow. Haskell '06: Proceedings of the 2006 ACM SIGPLAN workshop on Haskell, Portland, Oregon, ACM Press, September 2006<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn-sem.htm Imprecise Exceptions, Co-Inductively]<br />
:Andy Moran, Soeren Lassen, and Simon Peyton Jones. HOOTS'99.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm A semantics for imprecise exceptions]<br />
:Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Language Design and Implementation (PLDI'99), Atlanta.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm Asynchronous exceptions in Haskell]<br />
:Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy, PLDI'01.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/except6.ps.gz Handling Exceptions in Haskell]<br />
:A. Reid, Research Report YALEU/DCS/RR-1175, Yale University, August, 1998<br />
<br />
==Lexically scoped type variables==<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/papers/scoped%2Dtyvars/ Lexically scoped type variables]<br />
:Simon Peyton Jones and Mark Shields. 2004.<br />
<br />
==Records==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
:Mark Jones and Simon Peyton Jones, Haskell Workshop 1999.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/scopedlabels.pdf Extensible records with scoped labels]<br />
:Daan Leijen. The 2005 Symposium on Trends in Functional Programming (TFP'05), Tallin, Estonia, September 2005.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/fclabels.pdf First-class labels for extensible rows]<br />
:Daan Leijen. Technical Report UU-CS-2004-51, Departement of Computer Science, Universiteit Utrecht, 2004.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/h-wkshop95a/index.html Haskell Records]<br />
:J. Peterson, A. Reid, Proceedings of the Haskell Workshop, La Jolla, June 1995. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/96-3.ps.gz A Polymorphic Type System for Extensible Records and Variants]<br />
:Benedict R. Gaster and Mark P. Jones. Department of Computer Science, University of Nottingham. Technical report NOTTCS-TR-96-3. November 1996.<br />
<br />
==Meta programming==<br />
<br />
;[http://research.microsoft.com/copyright/accept.asp?path=/users/simonpj/papers/dyntyping.ps.gz&pub=ACM Dynamic typing as staged type inference]<br />
:MB Shields, T Sheard, and SL Peyton Jones, POPL98.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/meta-haskell/index.htm Template meta-programming for Haskell]<br />
:Tim Sheard and Simon Peyton Jones, Proceedings of the Haskell Workshop, Pittsburgh, 2002<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCK04.html Optimising Embedded DSLs using Template Haskell]<br />
:Sean Seefried, Manuel M. T. Chakravarty, and Gabriele Keller. In Gabor Karsai and Eelco Visser, editors, Third International Conference on Generative Programming and Component Engineering (GPCE'04), LNCS 3286, Springer-Verlag, pages 186-205, 2004. [An earlier draft was presented at the IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, 2003.<br />
<br />
;[http://www.haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps Unrolling and Simplifying Expressions with Template Haskell]<br />
:Ian Lynagh, May 2003.<br />
<br />
;[http://www.haskell.org/th/papers/hlpp.ps Automatic skeletons in Template Haskell]<br />
:Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. Proceedings of 2003 Workshop on High Level Parallel Programming, Paris, France<br />
<br />
;[http://www.haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps Typing Template Haskell: Soft Types]<br />
:Ian Lynagh, August 2004.<br />
<br />
==Dynamic typing==<br />
<br />
;[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/BaSw02.bib Typing dynamic typing]<br />
:A. I. Baars and S. D. Swierstra. In S. Peyton Jones, editor, Proceedings of the seventh ACM SIGPLAN international conference on Functional programming, pages 157--166. ACM Press, 2002<br />
<br />
==Parametricity==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps.gz Theorems for free!]<br />
:Philip Wadler. 4'th International Conference on Functional Programming and Computer Architecture, London, September 1989.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/seqFinal.pdf The Impact of seq on Free Theorems-Based Program Transformations]<br />
:Patricia Johann and Janis Voigtländer, Fundamenta Informaticae, vol. 69(1-2), pp. 63-102, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/TCS.pdf Selective strictness and parametricity in structural operational semantics, inequationally]<br />
:Janis Voigtländer and Patricia Johann, Theoretical Computer Science, vol. 388(1-3), pp. 290-318, 2007.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/pepm09-voigtlaender.pdf Proving Correctness via Free Theorems: The Case of the destroy/build-Rule]<br />
:Janis Voigtländer. Workshop on Partial Evaluation and Program Manipulation (PEPM'08), Proceedings, ACM Press, 2008.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/iandc.pdf A family of syntactic logical relations for the semantics of Haskell-like languages]<br />
:Patricia Johann and Janis Voigtländer, Information and Computation, vol. 207(2), pp. 341-368, 2009.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/tlca09.pdf Parametricity for Haskell with Imprecise Error Semantics]<br />
:Florian Stenger and Janis Voigtländer. International Conference on Typed Lambda Calculi and Applications (TLCA'09), Proceedings, Springer-Verlag, 2009.<br />
<br />
<br />
==Type classes==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz How to make ad-hoc polymorphism less ad hoc]<br />
:Philip Wadler and Stephen Blott. 16'th Symposium on Principles of Programming Languages, ACM Press, Austin, Texas, January 1989.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/classhask.ps.gz Type classes in Haskell, CV Hall, K Hammond, SL Peyton Jones, and PL Wadler]<br />
:European Symposium On Programming, LNCS 788, Springer Verlag, pp. 241-256, April 1994. (Cited by 131)<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/pldi93.html Implementing Type Classes]<br />
:John Peterson and Mark P. Jones, In Proceedings of ACM SIGPLAN Symposium on Programming Language Design and Implementation, ACM SIGPLAN, June 1993. (Cited by 40)<br />
<br />
;[http://www.cs.chalmers.se/pub/cs-reports/papers/overload-fpca-93.ps.Z Implementing Haskell overloading]<br />
:Lennart Augustsson, 1993. FPCA. 65-73<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/springschool.html Functional Programming with Overloading and Higher-Order Polymorphism]<br />
:Mark P. Jones, First International Spring School on Advanced Functional Programming Techniques, Baastad, Sweden, Springer-Verlag Lecture Notes in Computer Science 925, May 1995.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/type-class-design-space Type classes: exploring the design space]<br />
:Simon Peyton Jones, Mark Jones, Erik Meijer, Haskell Workshop 1997.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca93.html A system of constructor classes: overloading and implicit higher-order polymorphism]<br />
:Mark P. Jones, In FPCA '93: Conference on Functional Programming Languages and Computer Architecture, Copenhagen, Denmark, June 1993.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/overload2/overload2.ps.gz A second look at overloading]<br />
:Martin Odersky, Philip Wadler, Martin Wehr. 7'th International Conference on Functional Programming and Computer Architecture, ACM Press, San Diego, California, June 1995.<br />
<br />
;[http://citeseer.ist.psu.edu/laufer94combining.html Combining Type Classes and Existential Types]<br />
:Konstantin Laufer, Proceedings of the Latin American Informatic Conference (PANEL), 1994<br />
<br />
;[http://citeseer.ist.psu.edu/aufer95type.html Type Classes with Existential Types]<br />
:Konstantin Laufer, Journal of Functional Programming, 1996, May<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/DHCK06.html Modular Type Classes]<br />
:Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty and Gabriele Keller, 2006<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/4.pdf Named instances for Haskell type classes]<br />
:W Kahl, J Scheffczyk - Proc. Haskell Workshop, 2001 (Cited by 12)<br />
<br />
===Deriving type classes===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/derive.htm Derivable Type classes] <br />
:Ralf Hinze and Simon Peyton Jones, Haskell Workshop 2000.<br />
<br />
;[http://www.cis.upenn.edu/~sweirich/RepLib/ RepLib: A Library for Derivable Type Classes]<br />
:Stephanie Weirich 2006<br />
<br />
===Applications of type classes===<br />
<br />
;[http://okmij.org/ftp/Haskell/number-parameterized-types.html Number-parameterized types]<br />
:Oleg Kiselyov, The Monad.Reader. IssueFive. Oct 2nd, 2005<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/typecase.pdf TypeCase: a design pattern for type-indexed functions]<br />
:Bruno C. d. S. Oliveira, Jeremy Gibbons. Proceedings of the 2005 ACM SIGPLAN workshop on Haskell. Tallinn, Estonia. 98 - 109, 2005 ISBN:1-59593-071-X<br />
<br />
;[http://okmij.org/ftp/Haskell/types.html#Prepose Functional pearl: implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan, Proceedings of the 2004 ACM SIGPLAN workshop on Haskell, Snowbird, Utah, USA, 2004 ISBN 1-58113-850-4<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/extract-typeclassproofs.pdf Extracting Programs from Type Class Proofs]<br />
:Martin Sulzmann, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/coind-type-class-proofs.ps Co-induction and Type Improvement in Type Class Proofs]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey. 2005<br />
<br />
;[http://www.cs.nott.ac.uk/~ctm/faking.ps.gz Faking It (Simulating Dependent Types in Haskell)]<br />
:Conor McBride, Journal of Functional Programming, 12(4&5):375-392, July 2002<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/aophaskell.ps.gz Aspect-Oriented Programming with Type Classes]<br />
:Martin Sulzmann and Meng Wang, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/mpc08.pdf Asymptotic Improvement of Computations over Free Monads]<br />
:Janis Voigtländer. Mathematics of Program Construction (MPC'08), Proceedings, LNCS 5133:388-403, Springer-Verlag, 2008.<br />
<br />
<br />
==Undecidable instances==<br />
<br />
;[http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#undecidable-instances Undecidable instances]<br />
:GHC User's Guide.<br />
<br />
==Multi-parameter type classes==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/ghc-mptc-inf.ps Principal Type Inference for GHC-Style Multi-Parameter Type Classes]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey. In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/mptc-inf-old.pdf Type Inference for Multi-Parameter Type Classes]<br />
:Martin Sulzmann and Peter J. Stuckey. 2005<br />
<br />
;[http://ostrich.lcs.mit.edu/cgi-bin/pickbib?jfp::DugganO2002 Type-checking multi-parameter type classes]<br />
:Dominic Duggan and John Ophel, Journal of Functional Programming, 12(2):133-158, March 2002<br />
<br />
==Functional dependencies==<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fundeps.html Type Classes with Functional Dependencies]<br />
:Mark P. Jones, In Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/fd-chr/index.htm Sound and Decidable Type Inference for Functional Dependencies]<br />
:Gregory J. Duck, Simon Peyton Jones, Peter J. Stuckey, and Martin Sulzmann, European Symposium on Programming 2004 (ESOP'04).<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/jfp-fds-revised.pdf Understanding Functional Dependencies via Constraint Handling Rules]<br />
:Martin Sulzmann, Gregory J. Duck, Simon Peyton-Jones and Peter J. Stuckey.j To appear in Journal of Functional Programming. 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/afds.ps Associated Functional Dependencies]<br />
:Martin Sulzmann and Edmund Soon Lee Lam. 2005<br />
<br />
==Constraint Handling Rules==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/aplas06-invited.pdf Type Processing by Constraint Reasoning]<br />
:Peter J. Stuckey, Martin Sulzmann and Jeremy Wazny, In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/chr-stm.ps A Concurrent Constraint Handling Rules Implementation in Haskell with Software Transactional Memory]<br />
:Edmund S.L. Lam and Martin Sulzmann<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/chr06-observable.ps Observable Confluence for Constraint Handling Rules]<br />
:Gregory J. Duck, Peter J. Stuckey and Martin Sulzmann<br />
<br />
==Generalised Algebraic Data Types (GADTs)==<br />
<br />
;[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs]<br />
:Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. Submitted to PLDI 2005<br />
<br />
;[http://www.cis.upenn.edu/~geoffw/research/papers/MS-CIS-05-26.pdf Wobbly types: type inference for generalised algebraic data types]<br />
:S Peyton Jones, G. Washburn, and S. Weirich. 2004.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F]<br />
:Martin Sulzmann and Meng Wang. 2005<br />
<br />
;[http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types]<br />
:François Pottier and Yann Régis-Gianas, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/gadt-short.ps Type Inference for GADTs via Herbrand Constraint Abduction]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey, 2006 <br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/tr-eadt.ps.gz A Framework for Extended Algebraic Data Types]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey, 2006<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/implication_constraints.pdf Complete and Decidable Type Inference for GADTs]<br />
:Tom Schrijvers, Simon Peyton-Jones, Martin Sulzmann and Dimitrios Vytiniotis, 2009.<br />
<br />
See also the [[GADT]] page.<br />
<br />
==Parametric Regular Data Types==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/parametric-regular.ps Type Inference and Compilation for Parametric Regular Data Types]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/haskell-xduce.ps The Marriage of Haskell and XDuce]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu<br />
<br />
==Type Families and Associated types==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/assoc.pdf Associated types with class]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, Simon Marlow) POPL '05: Proceedings of the 32nd ACM SIGPLAN-SIGACT sysposium on Principles of programming languages, pages 1--13, Long Beach, California, USA, ACM Press, 2005<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming, ACM Press, pages 241-253, 2005.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/diplom ML Modules and Haskell Type Classes: A Constructive Comparison]<br />
:Stefan Wehr Diplomarbeit. Albert-Ludwigs-Universitt Freiburg, Fakultt fr Angewandte Wissenschaften, Institut fr Informatik, November 2005. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCP06.html System F with Type Equality Coercions]<br />
:Martin Sulzmann, Manuel M. T. Chakravarty, and Simon Peyton Jones.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/type_functions.pdf Towards Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Martin Sulzmann, and Manuel Chakravarty. In Proceedings of IFL' 07, Freiburg, Germany, 2007.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/draft_type_functions_2008.pdf Type Checking with Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Manuel Chakravarty, and Martin Sulzmann. In Proceedings of ICFP' 08, Victoria, Canada, 2008.<br />
<br />
<br />
==Arbitrary-rank polymorphism==<br />
<br />
;[http://www.ubka.uni-karlsruhe.de/vvv/1996/informatik/81/81.pdf.gz Putting type annotations to work]<br />
:Martin Odersky and Konstantin Läufer. Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. St. Petersburg Beach, Florida, United States. 54 - 67 1996 ISBN 0-89791-769-3<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext%3Ffulltextid%3D445910 Practical type inference for arbitrary-rank types]<br />
:SP Jones, M Shields - Submitted to the Journal of Functional Programming, 2005<br />
<br />
==Phantom types==<br />
<br />
;[http://techreports.library.cornell.edu:8081/Dienst/UI/1.0/Display/cul.cis/TR2003-1901 First-class phantom types]<br />
:James Cheney and Ralf Hinze. Technical Report TR2003-1901, Cornell University, 2003.<br />
<br />
;[http://ttic.uchicago.edu/~fluet/research/phantom-subtyping/jfp06/jfp06.pdf Phantom Types and Subtyping]<br />
:Matthew Fluet and Riccardo Pucella. Submitted to the Journal of Functional Programming, 2006.<br />
<br />
==Implicit parameters==<br />
<br />
;[http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/implicit.ps Implicit Parameters: Dynamic Scoping with Static Types]<br />
:Jeffrey Lewis, Mark Shields, Erik Meijer and John Launchbury. POPL'00. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. J. Funct. Program. 14(5): 489-502 (2004) <br />
<br />
;[http://www.cs.uu.nl/pub/RUU/CS/techreps/CS-2004/2004-059.pdf Explicit Implicit Parameters]<br />
:A. Dijkstra and S. D. Swierstra. UU-CS 2004-059, 2004.<br />
<br />
==Object oriented Haskell==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] <br />
:Mark Shields and Simon Peyton Jones; BABEL workshop '01.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/PC03.html Interfacing Haskell with Object-Oriented Languages]<br />
:Andr T. H. Pang and Manuel M. T. Chakravarty. In Greg Michaelson and Phil Trinder, editors, Implementation of Functional Languages: 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, LNCS 3145, Springer-Verlag, pages 20-36, 2004. <br />
<br />
;[http://citeseer.ist.psu.edu/118134.html Haskell++: An Object-Oriented Extension of Haskell]<br />
:Jan Sparud and John Hughes. Haskell Workshop 1995<br />
<br />
;[http://homepages.cwi.nl/~ralf/OOHaskell/ Haskell's overlooked object system]<br />
:Oleg Kiselyov and Ralf Lämmel, submitted for journal publication; online since 30 Sep. 2004;<br />
<br />
==Restricted Datatypes==<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Papers/restricted-datatypes.ps Restricted datatypes]<br />
:John Hughes. 1999 Haskell workshop<br />
<br />
==Patterns==<br />
<br />
;[http://www.cs.yale.edu/homes/tullsen/patterns.ps First Class Patterns]<br />
:Mark Tullsen. Practical Aspects of Declarative Languages, Second International Workshop, PADL 2000. volume 1753 of Lecture Notes in Computer Science. January 2000. <br />
<br />
===Pattern guards===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/pat.htm Pattern Guards and Transformational Patterns]<br />
:Martin Erwig and Simon Peyton Jones; Haskell Workshop 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Haskell/guards.html A new view of guards]<br />
:Simon Peyton Jones, April 1997<br />
<br />
===Views===<br />
<br />
;[http://www.haskell.org/development/views.html Views: An Extension to Haskell Pattern Matching]<br />
:Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson and Phil Wadler.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps.gz Views: A way for pattern matching to cohabit with data abstraction]<br />
:POPL 14 (1987), 307-313.<br />
<br />
==Qualified types==<br />
<br />
;[http://haskell.readscheme.org/servlets/cite.ss?pattern=mpj-jones1994a Qualified Types: Theory and Practice]<br />
:Mark P. Jones. PhD. Thesis. Yale University. November 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca95.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. FPCA '95: Conference on Functional Programming Languages and Computer Architecture. June 1995.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-1040.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-1040. June 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-989.ps Coherence for qualified types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-989. September 1993. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/rev-qual-types.ps A theory of qualified types]<br />
:Mark P. Jones. ESOP '92: European Symposium on Programming. Lecture Notes in Computer Science, 582. February 1992. (Cited by 68)<br />
<br />
==Polymorphic recursion==<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D169692 Type inference with polymorphic recursion]<br />
:F Henglein - ACM Transactions on Programming Languages and Systems (1993)<br />
<br />
;[http://www.jucs.org/jucs_9_8/practical_type_inference_for/paper.pdf Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell]<br />
:C Vasconcellos, L Figueiredo, C Camarao - Journal of Universal Computer Science, 2003<br />
<br />
;[http://www.dcc.ufmg.br/~camarao/ml0-impl.ps Type Inference for Polymorphic Recursive Definitions: a Specification in Haskell]<br />
:L Figueiredo, C Camarao<br />
<br />
[[Category:Research]]<br />
[[Category:Type-level programming]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Simonpj/Talk:FunWithTypeFuns&diff=28212Simonpj/Talk:FunWithTypeFuns2009-05-15T11:11:40Z<p>Tschrijvers: </p>
<hr />
<div>= Fun with Type Functions =<br />
<br />
Oleg Kiselyov, Ken Shan, and Simon Peyton Jones have a draft paper<br />
* '''[http://research.microsoft.com/~simonpj/papers/assoc-types/typefun.pdf Fun With Type Functions]'''<br />
which will appear in the proceedings of Tony Hoare's 75th birthday celebration.<br />
<blockquote><br />
'''Abstract'''. Tony Hoare has always been a leader in writing down and proving<br />
properties of programs. To prove properties of programs automatically,<br />
the most widely used technology today is by far the ubiquitous type checker.<br />
Alas, static type systems inevitably exclude some good programs<br />
and allow some bad ones. This dilemma motivates us to describe some fun we've<br />
been having with Haskell, by making the type system more expressive<br />
without losing the benefits of automatic proof and compact expression.<br />
<p><br />
Haskell's type system extends Hindley-Milner with two distinctive<br />
features: polymorphism over type constructors and overloading<br />
using type classes. These features have been integral to Haskell<br />
since its beginning, and they are widely used and appreciated. More recently, Haskell has been enriched with<br />
''type families'', or ''associated types'', <br />
which allows functions on types to be<br />
expressed as straightforwardly as functions on values. This facility<br />
makes it easier for programmers to effectively extend the compiler by<br />
writing functional programs that execute during type-checking.<br />
</p><p><br />
This paper gives a programmer's tour of type families as they are<br />
supported in GHC today.<br />
</p></blockquote><br />
<br />
This Wiki page is a discussion page for the paper. If you are kind enough to read this paper, please help us by jotting down any thoughts it triggers off. Things to think about:<br />
* What is unclear?<br />
* What is omitted that you'd like to see?<br />
* Do you have any cool examples that are of a somewhat different character than the ones we describe? (If so, do explain the example on this page!)<br />
<br />
Deadline is sometime in June 2009.<br />
<br />
You can identify your entries by preceding them with four tildes. Doing so adds your name, and the date. Thus:<br />
<br />
:[[User:Simonpj|Simonpj]] 08:42, 19 April 2007 (UTC) Note from Simon<br />
<br />
<br />
If you say who you are in this way, we'll be able to acknowledge your help in a revised version of the paper.<br />
<br />
------------------------<br />
Add comments here (newest at the top):<br />
<br />
[[User:bjpop|BerniePope]] 06:18, Fri 15 May 2009 (UTC) Typo in Appendix B.<br />
<br />
"GHC should noat" -> "GHC should not"<br />
<br />
[[User:Tanimoto|tanimoto]] 02:17, 15 May 2009 (UTC) Typo in references<br />
<br />
In reference [32], page 30, Oleg's last name is misspelled as "Kiselov".<br />
<br />
<br />
[[User:Ryani|Ryani]] 23:01, 14 May 2009 (UTC) Fun paper! Comments:<br />
<br />
I was writing a generic finite map a while ago and determined that the generic memoized trie was better in almost all cases; it was simpler semantically and didn't have a significant performance difference. Then you have "type Map k v = Table k (Maybe v)". Is it worth calling out this special case in its own section?<br />
<br />
Also, in respose to ChrisKuklewicz, I think the type for "cons" is correct, but perhaps one instance should be given as an example.<br />
<br />
[[User:Dave Menendez|Dave Menendez]] 16:52, 14 May 2009 (UTC) On page 11, you refer to a "specialised instance for Table Int that uses some custom <br />
(but infinite!) tree representation for Int." Was this meant to be Integer? Surely any tree representation for Int would be large but finite. <br />
<br />
-------------------<br />
Peter Verswyvelen and I have been working on some type family fun to give us generalised partial application (even to the point of being able to cope with giving arguments, but not a function). I don't know if it really makes any interesting point that you didn't already in the paper, but it's certainly fun...<br />
<br />
<haskell><br />
{-# LANGUAGE TypeFamilies, EmptyDataDecls, TypeOperators, FlexibleInstances, FlexibleContexts #-}<br />
<br />
module Burn2 where<br />
<br />
newtype V a = V a -- A value<br />
data B a = B -- A value we don't want to provide yet<br />
<br />
-- Type level homogenous lists (well just tuples in a list-like syntax really)<br />
data Nil a = Nil<br />
data a :& b = !a :& !b<br />
<br />
infixr 5 :& <br />
<br />
class Apply funargs where<br />
type Result funargs :: *<br />
apply :: funargs -> Result funargs<br />
<br />
instance (Apply (V b :& rest), a ~ c) => Apply (V (a->b) :& V c :& rest) where<br />
type Result (V (a->b) :& V c :& rest) = Result (V b :& rest)<br />
apply (V f :& V a :& rest) = apply $ V (f a) :& rest<br />
<br />
instance (Apply (V b :& rest), a ~ c) => Apply (B (a->b) :& V c :& rest) where<br />
type Result (B (a->b) :& V c :& rest) = (a->b) -> Result (V b :& rest)<br />
apply (B :& V a :& rest) = \f -> apply $ V (f a) :& rest<br />
<br />
instance (Apply (V b :& rest), a ~ c) => Apply (V (a->b) :& B c :& rest) where<br />
type Result (V (a->b) :& B c :& rest) = a -> Result (V b :& rest)<br />
apply (V f :& B :& rest) = \a -> apply $ V (f a) :& rest<br />
<br />
instance (Apply (V b :& rest), a ~ c) => Apply (B (a->b) :& B c :& rest) where<br />
type Result (B (a->b) :& B c :& rest) = (a->b) -> a -> Result (V b :& rest)<br />
apply (B :& B :& rest) = \f a -> apply $ V (f a) :& rest<br />
<br />
instance Apply (V a :& Nil b) where<br />
type Result (V a :& Nil b) = a<br />
apply (V a :& Nil) = a<br />
<br />
instance Apply (B a :& Nil b) where<br />
type Result (B a :& Nil b) = B a<br />
apply (B :& Nil) = B<br />
<br />
v1 = apply (V 1 :& Nil)<br />
f1 = apply (B :& Nil)<br />
v2 = apply (V negate :& V 1 :& Nil)<br />
f3 = apply (V negate :& B :& Nil)<br />
v3 = apply (V f3 :& V 1 :& Nil)<br />
</haskell><br />
<br />
[[User:Beelsebob|Beelsebob]] 13:04, 14 May 2009 (UTC)<br />
<br />
<br />
--------------------------------------<br />
<br />
End of section 2.2, I think "cons :: a -> [b] -> [ResTy a b]" should be "cons :: a -> [b] -> ResTy a b"<br />
<br />
[[User:ChrisKuklewicz|ChrisKuklewicz]] 15:28, 14 May 2009 (UTC)<br />
<br />
<br />
--------------------------------------<br />
<br />
End of page 19 with footnote 9. I could not simply copy and paste the URL because of a stray space after the '-' in http://okmij.org/ftp/Haskell/keyword- arguments.lhs<br />
<br />
[[User:ChrisKuklewicz|ChrisKuklewicz]] 16:08, 14 May 2009 (UTC)<br />
<br />
--------------------------------------<br />
<br />
Typo "Mounier" --> "Monnier"<br />
<br />
[[User:Tschrijvers|Tom Schrijvers]] 11:11, 15 May 2009 (UTC)</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Type_systems&diff=23017Research papers/Type systems2008-09-20T13:14:05Z<p>Tschrijvers: added ICFP 2008 paper on open type functions</p>
<hr />
<div>__TOC__<br />
<br />
==Haskell semantics==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/static-semantics.dvi.gz A static semantics for Haskell]<br />
:SL Peyton Jones and PL Wadler, (draft), Department of Computing Science, University of Glasgow, 1992. (Cited by 20)<br />
<br />
;[http://haskell.org/onlinereport/dynamic-semantics.dvi.gz A Dynamic Semantics for Haskell] <br />
:Kevin Hammond and Cordelia Hall, (draft), University of Glasgow, 1992, 23 pages.<br />
<br />
;[http://citeseer.ist.psu.edu/424440.html Typing Haskell in Haskell] <br />
:Mark P. Jones, In Proceedings of the 1999 Haskell Workshop, Paris, France, October 1999. Published in Technical Report UU-CS-1999-28, Department of Computer Science, University of Utrecht. (Cited by 66)<br />
<br />
;[http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne/haskell_libs/hsparser.html HParser]<br />
:A parser for Haskell written purely in Haskell (using the Happy parser generator).<br />
<br />
;[http://www.cse.ogi.edu/~hallgren/Talks/LHiH/ A Lexer for Haskell in Haskell]<br />
:Thomas Hallgren, PacSoft Oregon Graduate Institute, 14 January, 2002<br />
<br />
;[http://citeseer.ist.psu.edu/launchbury93natural.html A Natural Semantics for Lazy Evaluation]<br />
:John Launchbury, Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, 144--154, 1993.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/papers/11.ps A Space Semantics for Core Haskell]<br />
:Adam Bakewell. Proc. 2000 Haskell Workshop. September 2001.<br />
<br />
==Pure type systems==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/henk.ps.gz Henk: a typed intermediate language]<br />
:SL Peyton Jones and E Meijer, Proceedings of the Types in Compilation Workshop, Amsterdam, June 1997.<br />
<br />
;[http://www.cs.uu.nl/~johanj/MSc/jwroorda/ Pure Type Systems for Functional Programming]<br />
:Jan-Willem Roorda, Masters Thesis, University of Utrecht, INF/SCR-00-13, available online, 2000<br />
<br />
==Dependent Types==<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/ydtm.pdf Why Dependent Types Matter]<br />
:Thorsten Altenkirch and Conor McBride and James McKinna, Manuscript, available online, April, 2005. (Cited by 7)<br />
<br />
;[http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html Simply Easy! An Implementation of a Dependently Typed Lambda Calculus]<br />
:Andres Löh, Conor McBride and Wouter Swierstra, 2007.<br />
<br />
==Unboxed values==<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z Unboxed values as first class citizens]<br />
:SL Peyton Jones and J Launchbury, Functional Programming Languages and Computer Architecture (FPCA'91), Boston, LNCS 523, Springer Verlag, Sept 1991, pp636-666. (Cited by 105)<br />
<br />
==Modules==<br />
<br />
;[http://www.cse.ogi.edu/~diatchki/papers/modules98.pdf A Formal Specification of the Haskell 98 Module System]<br />
:Iavor S. Diatchki, Mark P. Jones, and Thomas Hallgren. Proceedings of the 2002 ACM SIGPLAN workshop on Haskell. Pittsburgh, Pennsylvania. 17 - 28 2002 ISBN 1-58113-605-6 (Cited by 12)<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/first-class-modules/index.htm First class modules for Haskell]<br />
:Mark Shields and Simon Peyton Jones; FOOL'02.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/Nicklisch-modules.ps.gz An exploration of modular programs]<br />
:Electronic proceedings of the 1996 Glasgow Functional Programming Workshop, J Nicklisch and SL Peyton Jones, Ullapool, July 1996.<br />
<br />
==Exceptions==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf An Extensible Dynamically-Typed Hierarchy of Exceptions]<br />
:Simon Marlow. Haskell '06: Proceedings of the 2006 ACM SIGPLAN workshop on Haskell, Portland, Oregon, ACM Press, September 2006<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn-sem.htm Imprecise Exceptions, Co-Inductively]<br />
:Andy Moran, Soeren Lassen, and Simon Peyton Jones. HOOTS'99.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm A semantics for imprecise exceptions]<br />
:Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Language Design and Implementation (PLDI'99), Atlanta.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm Asynchronous exceptions in Haskell]<br />
:Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy, PLDI'01.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/except6.ps.gz Handling Exceptions in Haskell]<br />
:A. Reid, Research Report YALEU/DCS/RR-1175, Yale University, August, 1998<br />
<br />
==Lexically scoped type variables==<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/papers/scoped%2Dtyvars/ Lexically scoped type variables]<br />
:Simon Peyton Jones and Mark Shields. 2004.<br />
<br />
==Records==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
:Mark Jones and Simon Peyton Jones, Haskell Workshop 1999.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/scopedlabels.pdf Extensible records with scoped labels]<br />
:Daan Leijen. The 2005 Symposium on Trends in Functional Programming (TFP'05), Tallin, Estonia, September 2005.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/fclabels.pdf First-class labels for extensible rows]<br />
:Daan Leijen. Technical Report UU-CS-2004-51, Departement of Computer Science, Universiteit Utrecht, 2004.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/h-wkshop95a/index.html Haskell Records]<br />
:J. Peterson, A. Reid, Proceedings of the Haskell Workshop, La Jolla, June 1995. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/96-3.ps.gz A Polymorphic Type System for Extensible Records and Variants]<br />
:Benedict R. Gaster and Mark P. Jones. Department of Computer Science, University of Nottingham. Technical report NOTTCS-TR-96-3. November 1996.<br />
<br />
==Meta programming==<br />
<br />
;[http://research.microsoft.com/copyright/accept.asp?path=/users/simonpj/papers/dyntyping.ps.gz&pub=ACM Dynamic typing as staged type inference]<br />
:MB Shields, T Sheard, and SL Peyton Jones, POPL98.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/meta-haskell/index.htm Template meta-programming for Haskell]<br />
:Tim Sheard and Simon Peyton Jones, Proceedings of the Haskell Workshop, Pittsburgh, 2002<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCK04.html Optimising Embedded DSLs using Template Haskell]<br />
:Sean Seefried, Manuel M. T. Chakravarty, and Gabriele Keller. In Gabor Karsai and Eelco Visser, editors, Third International Conference on Generative Programming and Component Engineering (GPCE'04), LNCS 3286, Springer-Verlag, pages 186-205, 2004. [An earlier draft was presented at the IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, 2003.<br />
<br />
;[http://www.haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps Unrolling and Simplifying Expressions with Template Haskell]<br />
:Ian Lynagh, May 2003.<br />
<br />
;[http://www.haskell.org/th/papers/hlpp.ps Automatic skeletons in Template Haskell]<br />
:Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. Proceedings of 2003 Workshop on High Level Parallel Programming, Paris, France<br />
<br />
;[http://www.haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps Typing Template Haskell: Soft Types]<br />
:Ian Lynagh, August 2004.<br />
<br />
==Dynamic typing==<br />
<br />
;[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/BaSw02.bib Typing dynamic typing]<br />
:A. I. Baars and S. D. Swierstra. In S. Peyton Jones, editor, Proceedings of the seventh ACM SIGPLAN international conference on Functional programming, pages 157--166. ACM Press, 2002<br />
<br />
==Parametricity==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps.gz Theorems for free!]<br />
:Philip Wadler. 4'th International Conference on Functional Programming and Computer Architecture, London, September 1989.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/seqFinal.pdf The Impact of seq on Free Theorems-Based Program Transformations]<br />
:Patricia Johann and Janis Voigtländer, Fundamenta Informaticae, vol. 69(1-2), pp. 63-102, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/TCS.pdf Selective strictness and parametricity in structural operational semantics, inequationally]<br />
:Janis Voigtländer and Patricia Johann, Theoretical Computer Science, vol. 388(1-3), pp. 290-318, 2007.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/pepm09-voigtlaender.pdf Proving Correctness via Free Theorems: The Case of the destroy/build-Rule]<br />
:Janis Voigtländer. Workshop on Partial Evaluation and Program Manipulation (PEPM'08), Proceedings, ACM Press, 2008.<br />
<br />
==Type classes==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz How to make ad-hoc polymorphism less ad hoc]<br />
:Philip Wadler and Stephen Blott. 16'th Symposium on Principles of Programming Languages, ACM Press, Austin, Texas, January 1989.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/classhask.ps.gz Type classes in Haskell, CV Hall, K Hammond, SL Peyton Jones, and PL Wadler]<br />
:European Symposium On Programming, LNCS 788, Springer Verlag, pp. 241-256, April 1994. (Cited by 131)<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/pldi93.html Implementing Type Classes]<br />
:John Peterson and Mark P. Jones, In Proceedings of ACM SIGPLAN Symposium on Programming Language Design and Implementation, ACM SIGPLAN, June 1993. (Cited by 40)<br />
<br />
;[http://www.cs.chalmers.se/pub/cs-reports/papers/overload-fpca-93.ps.Z Implementing Haskell overloading]<br />
:Lennart Augustsson, 1993. FPCA. 65-73<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/springschool.html Functional Programming with Overloading and Higher-Order Polymorphism]<br />
:Mark P. Jones, First International Spring School on Advanced Functional Programming Techniques, Baastad, Sweden, Springer-Verlag Lecture Notes in Computer Science 925, May 1995.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/type-class-design-space Type classes: exploring the design space]<br />
:Simon Peyton Jones, Mark Jones, Erik Meijer, Haskell Workshop 1997.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca93.html A system of constructor classes: overloading and implicit higher-order polymorphism]<br />
:Mark P. Jones, In FPCA '93: Conference on Functional Programming Languages and Computer Architecture, Copenhagen, Denmark, June 1993.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/overload2/overload2.ps.gz A second look at overloading]<br />
:Martin Odersky, Philip Wadler, Martin Wehr. 7'th International Conference on Functional Programming and Computer Architecture, ACM Press, San Diego, California, June 1995.<br />
<br />
;[http://citeseer.ist.psu.edu/laufer94combining.html Combining Type Classes and Existential Types]<br />
:Konstantin Laufer, Proceedings of the Latin American Informatic Conference (PANEL), 1994<br />
<br />
;[http://citeseer.ist.psu.edu/aufer95type.html Type Classes with Existential Types]<br />
:Konstantin Laufer, Journal of Functional Programming, 1996, May<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/DHCK06.html Modular Type Classes]<br />
:Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty and Gabriele Keller, 2006<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/4.pdf Named instances for Haskell type classes]<br />
:W Kahl, J Scheffczyk - Proc. Haskell Workshop, 2001 (Cited by 12)<br />
<br />
===Deriving type classes===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/derive.htm Derivable Type classes] <br />
:Ralf Hinze and Simon Peyton Jones, Haskell Workshop 2000.<br />
<br />
;[http://www.cis.upenn.edu/~sweirich/RepLib/ RepLib: A Library for Derivable Type Classes]<br />
:Stephanie Weirich 2006<br />
<br />
===Applications of type classes===<br />
<br />
;[http://okmij.org/ftp/Haskell/number-parameterized-types.html Number-parameterized types]<br />
:Oleg Kiselyov, The Monad.Reader. IssueFive. Oct 2nd, 2005<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/typecase.pdf TypeCase: a design pattern for type-indexed functions]<br />
:Bruno C. d. S. Oliveira, Jeremy Gibbons. Proceedings of the 2005 ACM SIGPLAN workshop on Haskell. Tallinn, Estonia. 98 - 109, 2005 ISBN:1-59593-071-X<br />
<br />
;[http://okmij.org/ftp/Haskell/types.html#Prepose Functional pearl: implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan, Proceedings of the 2004 ACM SIGPLAN workshop on Haskell, Snowbird, Utah, USA, 2004 ISBN 1-58113-850-4<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/extract-typeclassproofs.pdf Extracting Programs from Type Class Proofs]<br />
:Martin Sulzmann, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/coind-type-class-proofs.ps Co-induction and Type Improvement in Type Class Proofs]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey. 2005<br />
<br />
;[http://www.cs.nott.ac.uk/~ctm/faking.ps.gz Faking It (Simulating Dependent Types in Haskell)]<br />
:Conor McBride, Journal of Functional Programming, 12(4&5):375-392, July 2002<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/aophaskell.ps.gz Aspect-Oriented Programming with Type Classes]<br />
:Martin Sulzmann and Meng Wang, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/mpc08.pdf Asymptotic Improvement of Computations over Free Monads]<br />
:Janis Voigtländer. Mathematics of Program Construction (MPC'08), Proceedings, LNCS 5133:388-403, Springer-Verlag, 2008.<br />
<br />
<br />
==Undecidable instances==<br />
<br />
;[http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#undecidable-instances Undecidable instances]<br />
:GHC User's Guide.<br />
<br />
==Multi-parameter type classes==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/ghc-mptc-inf.ps Principal Type Inference for GHC-Style Multi-Parameter Type Classes]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey. In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/mptc-inf-old.pdf Type Inference for Multi-Parameter Type Classes]<br />
:Martin Sulzmann and Peter J. Stuckey. 2005<br />
<br />
;[http://ostrich.lcs.mit.edu/cgi-bin/pickbib?jfp::DugganO2002 Type-checking multi-parameter type classes]<br />
:Dominic Duggan and John Ophel, Journal of Functional Programming, 12(2):133-158, March 2002<br />
<br />
==Functional dependencies==<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fundeps.html Type Classes with Functional Dependencies]<br />
:Mark P. Jones, In Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/fd-chr/index.htm Sound and Decidable Type Inference for Functional Dependencies]<br />
:Gregory J. Duck, Simon Peyton Jones, Peter J. Stuckey, and Martin Sulzmann, European Symposium on Programming 2004 (ESOP'04).<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/jfp-fds-revised.pdf Understanding Functional Dependencies via Constraint Handling Rules]<br />
:Martin Sulzmann, Gregory J. Duck, Simon Peyton-Jones and Peter J. Stuckey.j To appear in Journal of Functional Programming. 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/afds.ps Associated Functional Dependencies]<br />
:Martin Sulzmann and Edmund Soon Lee Lam. 2005<br />
<br />
==Constraint Handling Rules==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/aplas06-invited.pdf Type Processing by Constraint Reasoning]<br />
:Peter J. Stuckey, Martin Sulzmann and Jeremy Wazny, In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/chr-stm.ps A Concurrent Constraint Handling Rules Implementation in Haskell with Software Transactional Memory]<br />
:Edmund S.L. Lam and Martin Sulzmann<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/chr06-observable.ps Observable Confluence for Constraint Handling Rules]<br />
:Gregory J. Duck, Peter J. Stuckey and Martin Sulzmann<br />
<br />
==Generalised Algebraic Data Types (GADTs)==<br />
<br />
;[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs]<br />
:Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. Submitted to PLDI 2005<br />
<br />
;[http://www.cis.upenn.edu/~geoffw/research/papers/MS-CIS-05-26.pdf Wobbly types: type inference for generalised algebraic data types]<br />
:S Peyton Jones, G. Washburn, and S. Weirich. 2004.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F]<br />
:Martin Sulzmann and Meng Wang. 2005<br />
<br />
;[http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types]<br />
:François Pottier and Yann Régis-Gianas, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/gadt-short.ps Type Inference for GADTs via Herbrand Constraint Abduction]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey, 2006 <br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/tr-eadt.ps.gz A Framework for Extended Algebraic Data Types]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey, 2006<br />
<br />
See also the [[GADT]] page.<br />
<br />
==Parametric Regular Data Types==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/parametric-regular.ps Type Inference and Compilation for Parametric Regular Data Types]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/haskell-xduce.ps The Marriage of Haskell and XDuce]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu<br />
<br />
==Type Families and Associated types==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/assoc.pdf Associated types with class]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, Simon Marlow) POPL '05: Proceedings of the 32nd ACM SIGPLAN-SIGACT sysposium on Principles of programming languages, pages 1--13, Long Beach, California, USA, ACM Press, 2005<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming, ACM Press, pages 241-253, 2005.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/diplom ML Modules and Haskell Type Classes: A Constructive Comparison]<br />
:Stefan Wehr Diplomarbeit. Albert-Ludwigs-Universitt Freiburg, Fakultt fr Angewandte Wissenschaften, Institut fr Informatik, November 2005. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCP06.html System F with Type Equality Coercions]<br />
:Martin Sulzmann, Manuel M. T. Chakravarty, and Simon Peyton Jones.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/type_functions.pdf Towards Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Martin Sulzmann, and Manuel Chakravarty. In Proceedings of IFL' 07, Freiburg, Germany, 2007.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/draft_type_functions_2008.pdf Type Checking with Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Manuel Chakravarty, and Martin Sulzmann. In Proceedings of ICFP' 08, Victoria, Canada, 2008.<br />
<br />
<br />
==Arbitrary-rank polymorphism==<br />
<br />
;[http://www.ubka.uni-karlsruhe.de/vvv/1996/informatik/81/81.pdf.gz Putting type annotations to work]<br />
:Martin Odersky and Konstantin Läufer. Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. St. Petersburg Beach, Florida, United States. 54 - 67 1996 ISBN 0-89791-769-3<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext%3Ffulltextid%3D445910 Practical type inference for arbitrary-rank types]<br />
:SP Jones, M Shields - Submitted to the Journal of Functional Programming, 2005<br />
<br />
==Phantom types==<br />
<br />
;[http://techreports.library.cornell.edu:8081/Dienst/UI/1.0/Display/cul.cis/TR2003-1901 First-class phantom types]<br />
:James Cheney and Ralf Hinze. Technical Report TR2003-1901, Cornell University, 2003.<br />
<br />
;[http://ttic.uchicago.edu/~fluet/research/phantom-subtyping/jfp06/jfp06.pdf Phantom Types and Subtyping]<br />
:Matthew Fluet and Riccardo Pucella. Submitted to the Journal of Functional Programming, 2006.<br />
<br />
==Implicit parameters==<br />
<br />
;[http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/implicit.ps Implicit Parameters: Dynamic Scoping with Static Types]<br />
:Jeffrey Lewis, Mark Shields, Erik Meijer and John Launchbury. POPL'00. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. J. Funct. Program. 14(5): 489-502 (2004) <br />
<br />
;[http://www.cs.uu.nl/pub/RUU/CS/techreps/CS-2004/2004-059.pdf Explicit Implicit Parameters]<br />
:A. Dijkstra and S. D. Swierstra. UU-CS 2004-059, 2004.<br />
<br />
==Object oriented Haskell==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] <br />
:Mark Shields and Simon Peyton Jones; BABEL workshop '01.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/PC03.html Interfacing Haskell with Object-Oriented Languages]<br />
:Andr T. H. Pang and Manuel M. T. Chakravarty. In Greg Michaelson and Phil Trinder, editors, Implementation of Functional Languages: 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, LNCS 3145, Springer-Verlag, pages 20-36, 2004. <br />
<br />
;[http://citeseer.ist.psu.edu/118134.html Haskell++: An Object-Oriented Extension of Haskell]<br />
:Jan Sparud and John Hughes. Haskell Workshop 1995<br />
<br />
;[http://homepages.cwi.nl/~ralf/OOHaskell/ Haskell's overlooked object system]<br />
:Oleg Kiselyov and Ralf Lämmel, submitted for journal publication; online since 30 Sep. 2004;<br />
<br />
==Restricted Datatypes==<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Papers/restricted-datatypes.ps Restricted datatypes]<br />
:John Hughes. 1999 Haskell workshop<br />
<br />
==Patterns==<br />
<br />
;[http://www.cs.yale.edu/homes/tullsen/patterns.ps First Class Patterns]<br />
:Mark Tullsen. Practical Aspects of Declarative Languages, Second International Workshop, PADL 2000. volume 1753 of Lecture Notes in Computer Science. January 2000. <br />
<br />
===Pattern guards===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/pat.htm Pattern Guards and Transformational Patterns]<br />
:Martin Erwig and Simon Peyton Jones; Haskell Workshop 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Haskell/guards.html A new view of guards]<br />
:Simon Peyton Jones, April 1997<br />
<br />
===Views===<br />
<br />
;[http://www.haskell.org/development/views.html Views: An Extension to Haskell Pattern Matching]<br />
:Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson and Phil Wadler.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps.gz Views: A way for pattern matching to cohabit with data abstraction]<br />
:POPL 14 (1987), 307-313.<br />
<br />
==Qualified types==<br />
<br />
;[http://haskell.readscheme.org/servlets/cite.ss?pattern=mpj-jones1994a Qualified Types: Theory and Practice]<br />
:Mark P. Jones. PhD. Thesis. Yale University. November 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca95.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. FPCA '95: Conference on Functional Programming Languages and Computer Architecture. June 1995.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-1040.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-1040. June 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-989.ps Coherence for qualified types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-989. September 1993. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/rev-qual-types.ps A theory of qualified types]<br />
:Mark P. Jones. ESOP '92: European Symposium on Programming. Lecture Notes in Computer Science, 582. February 1992. (Cited by 68)<br />
<br />
==Polymorphic recursion==<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D169692 Type inference with polymorphic recursion]<br />
:F Henglein - ACM Transactions on Programming Languages and Systems (1993)<br />
<br />
;[http://www.jucs.org/jucs_9_8/practical_type_inference_for/paper.pdf Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell]<br />
:C Vasconcellos, L Figueiredo, C Camarao - Journal of Universal Computer Science, 2003<br />
<br />
;[http://www.dcc.ufmg.br/~camarao/ml0-impl.ps Type Inference for Polymorphic Recursive Definitions: a Specification in Haskell]<br />
:L Figueiredo, C Camarao<br />
<br />
[[Category:Research]]<br />
[[Category:Type-level programming]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Type_systems&diff=16861Research papers/Type systems2007-11-15T02:33:51Z<p>Tschrijvers: </p>
<hr />
<div>__TOC__<br />
<br />
==Haskell semantics==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/static-semantics.dvi.gz A static semantics for Haskell]<br />
:SL Peyton Jones and PL Wadler, (draft), Department of Computing Science, University of Glasgow, 1992. (Cited by 20)<br />
<br />
;[http://haskell.org/onlinereport/dynamic-semantics.dvi.gz A Dynamic Semantics for Haskell] <br />
:Kevin Hammond and Cordelia Hall, (draft), University of Glasgow, 1992, 23 pages.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/thih.html Typing Haskell in Haskell] <br />
:Mark P. Jones, In Proceedings of the 1999 Haskell Workshop, Paris, France, October 1999. Published in Technical Report UU-CS-1999-28, Department of Computer Science, University of Utrecht. (Cited by 66)<br />
<br />
;[http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne/haskell_libs/hsparser.html HParser]<br />
:A parser for Haskell written purely in Haskell (using the Happy parser generator).<br />
<br />
;[http://www.cse.ogi.edu/~hallgren/Talks/LHiH/ A Lexer for Haskell in Haskell]<br />
:Thomas Hallgren, PacSoft Oregon Graduate Institute, 14 January, 2002<br />
<br />
;[http://citeseer.ist.psu.edu/launchbury93natural.html A Natural Semantics for Lazy Evaluation]<br />
:John Launchbury, Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, 144--154, 1993.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/papers/11.ps A Space Semantics for Core Haskell]<br />
:Adam Bakewell. Proc. 2000 Haskell Workshop. September 2001.<br />
<br />
==Pure type systems==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/henk.ps.gz Henk: a typed intermediate language]<br />
:SL Peyton Jones and E Meijer, Proceedings of the Types in Compilation Workshop, Amsterdam, June 1997.<br />
<br />
;[http://www.cs.uu.nl/~johanj/MSc/jwroorda/ Pure Type Systems for Functional Programming]<br />
:Jan-Willem Roorda, Masters Thesis, University of Utrecht, INF/SCR-00-13, available online, 2000<br />
<br />
==Dependent Types==<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/ydtm.pdf Why Dependent Types Matter]<br />
:Thorsten Altenkirch and Conor McBride and James McKinna, Manuscript, available online, April, 2005. (Cited by 7)<br />
<br />
;[http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html Simply Easy! An Implementation of a Dependently Typed Lambda Calculus]<br />
:Andres Löh, Conor McBride and Wouter Swierstra, 2007.<br />
<br />
==Unboxed values==<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z Unboxed values as first class citizens]<br />
:SL Peyton Jones and J Launchbury, Functional Programming Languages and Computer Architecture (FPCA'91), Boston, LNCS 523, Springer Verlag, Sept 1991, pp636-666. (Cited by 105)<br />
<br />
==Modules==<br />
<br />
;[http://www.cse.ogi.edu/~diatchki/papers/modules98.pdf A Formal Specification of the Haskell 98 Module System]<br />
:Iavor S. Diatchki, Mark P. Jones, and Thomas Hallgren. Proceedings of the 2002 ACM SIGPLAN workshop on Haskell. Pittsburgh, Pennsylvania. 17 - 28 2002 ISBN 1-58113-605-6 (Cited by 12)<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/first-class-modules/index.htm First class modules for Haskell]<br />
:Mark Shields and Simon Peyton Jones; FOOL'02.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/Nicklisch-modules.ps.gz An exploration of modular programs]<br />
:Electronic proceedings of the 1996 Glasgow Functional Programming Workshop, J Nicklisch and SL Peyton Jones, Ullapool, July 1996.<br />
<br />
==Exceptions==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf An Extensible Dynamically-Typed Hierarchy of Exceptions]<br />
:Simon Marlow. Haskell '06: Proceedings of the 2006 ACM SIGPLAN workshop on Haskell, Portland, Oregon, ACM Press, September 2006<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn-sem.htm Imprecise Exceptions, Co-Inductively]<br />
:Andy Moran, Soeren Lassen, and Simon Peyton Jones. HOOTS'99.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm A semantics for imprecise exceptions]<br />
:Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Language Design and Implementation (PLDI'99), Atlanta.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm Asynchronous exceptions in Haskell]<br />
:Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy, PLDI'01.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/except6.ps.gz Handling Exceptions in Haskell]<br />
:A. Reid, Research Report YALEU/DCS/RR-1175, Yale University, August, 1998<br />
<br />
==Lexically scoped type variables==<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/papers/scoped%2Dtyvars/ Lexically scoped type variables]<br />
:Simon Peyton Jones and Mark Shields. 2004.<br />
<br />
==Records==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
:Mark Jones and Simon Peyton Jones, Haskell Workshop 1999.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/scopedlabels.pdf Extensible records with scoped labels]<br />
:Daan Leijen. The 2005 Symposium on Trends in Functional Programming (TFP'05), Tallin, Estonia, September 2005.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/fclabels.pdf First-class labels for extensible rows]<br />
:Daan Leijen. Technical Report UU-CS-2004-51, Departement of Computer Science, Universiteit Utrecht, 2004.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/h-wkshop95a/index.html Haskell Records]<br />
:J. Peterson, A. Reid, Proceedings of the Haskell Workshop, La Jolla, June 1995. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/96-3.ps.gz A Polymorphic Type System for Extensible Records and Variants]<br />
:Benedict R. Gaster and Mark P. Jones. Department of Computer Science, University of Nottingham. Technical report NOTTCS-TR-96-3. November 1996.<br />
<br />
==Meta programming==<br />
<br />
;[http://research.microsoft.com/copyright/accept.asp?path=/users/simonpj/papers/dyntyping.ps.gz&pub=ACM Dynamic typing as staged type inference]<br />
:MB Shields, T Sheard, and SL Peyton Jones, POPL98.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/meta-haskell/index.htm Template meta-programming for Haskell]<br />
:Tim Sheard and Simon Peyton Jones, Proceedings of the Haskell Workshop, Pittsburgh, 2002<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCK04.html Optimising Embedded DSLs using Template Haskell]<br />
:Sean Seefried, Manuel M. T. Chakravarty, and Gabriele Keller. In Gabor Karsai and Eelco Visser, editors, Third International Conference on Generative Programming and Component Engineering (GPCE'04), LNCS 3286, Springer-Verlag, pages 186-205, 2004. [An earlier draft was presented at the IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, 2003.<br />
<br />
;[http://www.haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps Unrolling and Simplifying Expressions with Template Haskell]<br />
:Ian Lynagh, May 2003.<br />
<br />
;[http://www.haskell.org/th/papers/hlpp.ps Automatic skeletons in Template Haskell]<br />
:Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. Proceedings of 2003 Workshop on High Level Parallel Programming, Paris, France<br />
<br />
;[http://www.haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps Typing Template Haskell: Soft Types]<br />
:Ian Lynagh, August 2004.<br />
<br />
==Dynamic typing==<br />
<br />
;[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/BaSw02.bib Typing dynamic typing]<br />
:A. I. Baars and S. D. Swierstra. In S. Peyton Jones, editor, Proceedings of the seventh ACM SIGPLAN international conference on Functional programming, pages 157--166. ACM Press, 2002<br />
<br />
==Parametricity==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps.gz Theorems for free!]<br />
:Philip Wadler. 4'th International Conference on Functional Programming and Computer Architecture, London, September 1989.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/seqFinal.pdf The Impact of seq on Free Theorems-Based Program Transformations]<br />
:Patricia Johann and Janis Voigtländer, Fundamenta Informaticae, vol. 69(1-2), pp. 63-102, 2006.<br />
<br />
==Type classes==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz How to make ad-hoc polymorphism less ad hoc]<br />
:Philip Wadler and Stephen Blott. 16'th Symposium on Principles of Programming Languages, ACM Press, Austin, Texas, January 1989.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/classhask.ps.gz Type classes in Haskell, CV Hall, K Hammond, SL Peyton Jones, and PL Wadler]<br />
:European Symposium On Programming, LNCS 788, Springer Verlag, pp. 241-256, April 1994. (Cited by 131)<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/pldi93.html Implementing Type Classes]<br />
:John Peterson and Mark P. Jones, In Proceedings of ACM SIGPLAN Symposium on Programming Language Design and Implementation, ACM SIGPLAN, June 1993. (Cited by 40)<br />
<br />
;[http://www.cs.chalmers.se/pub/cs-reports/papers/overload-fpca-93.ps.Z Implementing Haskell overloading]<br />
:Lennart Augustsson, 1993. FPCA. 65-73<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/springschool.html Functional Programming with Overloading and Higher-Order Polymorphism]<br />
:Mark P. Jones, First International Spring School on Advanced Functional Programming Techniques, Baastad, Sweden, Springer-Verlag Lecture Notes in Computer Science 925, May 1995.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/type-class-design-space Type classes: exploring the design space]<br />
:Simon Peyton Jones, Mark Jones, Erik Meijer, Haskell Workshop 1997.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca93.html A system of constructor classes: overloading and implicit higher-order polymorphism]<br />
:Mark P. Jones, In FPCA '93: Conference on Functional Programming Languages and Computer Architecture, Copenhagen, Denmark, June 1993.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/overload2/overload2.ps.gz A second look at overloading]<br />
:Martin Odersky, Philip Wadler, Martin Wehr. 7'th International Conference on Functional Programming and Computer Architecture, ACM Press, San Diego, California, June 1995.<br />
<br />
;[http://citeseer.ist.psu.edu/laufer94combining.html Combining Type Classes and Existential Types]<br />
:Konstantin Laufer, Proceedings of the Latin American Informatic Conference (PANEL), 1994<br />
<br />
;[http://citeseer.ifi.unizh.ch/laeufer95type.html Type Classes with Existential Types]<br />
:Konstantin Laufer, Journal of Functional Programming, 1996, May<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/DHCK06.html Modular Type Classes]<br />
:Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty and Gabriele Keller, 2006<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/4.pdf Named instances for Haskell type classes]<br />
:W Kahl, J Scheffczyk - Proc. Haskell Workshop, 2001 (Cited by 12)<br />
<br />
===Deriving type classes===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/derive.htm Derivable Type classes] <br />
:Ralf Hinze and Simon Peyton Jones, Haskell Workshop 2000.<br />
<br />
;[http://www.cis.upenn.edu/~sweirich/RepLib/ RepLib: A Library for Derivable Type Classes]<br />
:Stephanie Weirich 2006<br />
<br />
===Applications of type classes===<br />
<br />
;[http://okmij.org/ftp/Haskell/number-parameterized-types.html Number-parameterized types]<br />
:Oleg Kiselyov, The Monad.Reader. IssueFive. Oct 2nd, 2005<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/typecase.pdf TypeCase: a design pattern for type-indexed functions]<br />
:Bruno C. d. S. Oliveira, Jeremy Gibbons. Proceedings of the 2005 ACM SIGPLAN workshop on Haskell. Tallinn, Estonia. 98 - 109, 2005 ISBN:1-59593-071-X<br />
<br />
;[http://okmij.org/ftp/Haskell/types.html#Prepose Functional pearl: implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan, Proceedings of the 2004 ACM SIGPLAN workshop on Haskell, Snowbird, Utah, USA, 2004 ISBN 1-58113-850-4<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/extract-typeclassproofs.pdf Extracting Programs from Type Class Proofs]<br />
:Martin Sulzmann, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/coind-type-class-proofs.ps Co-induction and Type Improvement in Type Class Proofs]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey. 2005<br />
<br />
;[http://www.cs.nott.ac.uk/~ctm/faking.ps.gz Faking It (Simulating Dependent Types in Haskell)]<br />
:Conor McBride, Journal of Functional Programming, 12(4&5):375-392, July 2002<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/aophaskell.ps.gz Aspect-Oriented Programming with Type Classes]<br />
:Martin Sulzmann and Meng Wang, 2006.<br />
<br />
==Undecidable instances==<br />
<br />
;[http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#undecidable-instances Undecidable instances]<br />
:GHC User's Guide.<br />
<br />
==Multi-parameter type classes==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/ghc-mptc-inf.ps Principal Type Inference for GHC-Style Multi-Parameter Type Classes]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey. In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/mptc-inf-old.pdf Type Inference for Multi-Parameter Type Classes]<br />
:Martin Sulzmann and Peter J. Stuckey. 2005<br />
<br />
;[http://ostrich.lcs.mit.edu/cgi-bin/pickbib?jfp::DugganO2002 Type-checking multi-parameter type classes]<br />
:Dominic Duggan and John Ophel, Journal of Functional Programming, 12(2):133-158, March 2002<br />
<br />
==Functional dependencies==<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fundeps.html Type Classes with Functional Dependencies]<br />
:Mark P. Jones, In Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/fd-chr/index.htm Sound and Decidable Type Inference for Functional Dependencies]<br />
:Gregory J. Duck, Simon Peyton Jones, Peter J. Stuckey, and Martin Sulzmann, European Symposium on Programming 2004 (ESOP'04).<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/jfp-fds-revised.pdf Understanding Functional Dependencies via Constraint Handling Rules]<br />
:Martin Sulzmann, Gregory J. Duck, Simon Peyton-Jones and Peter J. Stuckey.j To appear in Journal of Functional Programming. 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/afds.ps Associated Functional Dependencies]<br />
:Martin Sulzmann and Edmund Soon Lee Lam. 2005<br />
<br />
==Constraint Handling Rules==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/aplas06-invited.pdf Type Processing by Constraint Reasoning]<br />
:Peter J. Stuckey, Martin Sulzmann and Jeremy Wazny, In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/chr-stm.ps A Concurrent Constraint Handling Rules Implementation in Haskell with Software Transactional Memory]<br />
:Edmund S.L. Lam and Martin Sulzmann<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/chr06-observable.ps Observable Confluence for Constraint Handling Rules]<br />
:Gregory J. Duck, Peter J. Stuckey and Martin Sulzmann<br />
<br />
==Generalised Algebraic Data Types (GADTs)==<br />
<br />
;[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs]<br />
:Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. Submitted to PLDI 2005<br />
<br />
;[http://www.cis.upenn.edu/~geoffw/research/papers/MS-CIS-05-26.pdf Wobbly types: type inference for generalised algebraic data types]<br />
:S Peyton Jones, G. Washburn, and S. Weirich. 2004.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F]<br />
:Martin Sulzmann and Meng Wang. 2005<br />
<br />
;[http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types]<br />
:François Pottier and Yann Régis-Gianas, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/gadt-short.ps Type Inference for GADTs via Herbrand Constraint Abduction]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey, 2006 <br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/tr-eadt.ps.gz A Framework for Extended Algebraic Data Types]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey, 2006<br />
<br />
See also the [[GADT]] page.<br />
<br />
==Parametric Regular Data Types==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/parametric-regular.ps Type Inference and Compilation for Parametric Regular Data Types]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/haskell-xduce.ps The Marriage of Haskell and XDuce]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu<br />
<br />
==Associated types==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/assoc.pdf Associated types with class]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, Simon Marlow) POPL '05: Proceedings of the 32nd ACM SIGPLAN-SIGACT sysposium on Principles of programming languages, pages 1--13, Long Beach, California, USA, ACM Press, 2005<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming, ACM Press, pages 241-253, 2005.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/diplom ML Modules and Haskell Type Classes: A Constructive Comparison]<br />
:Stefan Wehr Diplomarbeit. Albert-Ludwigs-Universitt Freiburg, Fakultt fr Angewandte Wissenschaften, Institut fr Informatik, November 2005. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCP06.html System F with Type Equality Coercions]<br />
:Martin Sulzmann, Manuel M. T. Chakravarty, and Simon Peyton Jones.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/type_functions.pdf Towards Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Martin Sulzmann, and Manuel Chakravarty. In Proceedings of IFL' 07, Freiburg, Germany, 2007.<br />
<br />
<br />
==Arbitrary-rank polymorphism==<br />
<br />
;[http://www.ubka.uni-karlsruhe.de/vvv/1996/informatik/81/81.pdf.gz Putting type annotations to work]<br />
:Martin Odersky and Konstantin Läufer. Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. St. Petersburg Beach, Florida, United States. 54 - 67 1996 ISBN 0-89791-769-3<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext%3Ffulltextid%3D445910 Practical type inference for arbitrary-rank types]<br />
:SP Jones, M Shields - Submitted to the Journal of Functional Programming, 2005<br />
<br />
==Phantom types==<br />
<br />
;[http://techreports.library.cornell.edu:8081/Dienst/UI/1.0/Display/cul.cis/TR2003-1901 First-class phantom types]<br />
:James Cheney and Ralf Hinze. Technical Report TR2003-1901, Cornell University, 2003.<br />
<br />
;[http://ttic.uchicago.edu/~fluet/research/phantom-subtyping/jfp06/jfp06.pdf Phantom Types and Subtyping]<br />
:Matthew Fluet and Riccardo Pucella. Submitted to the Journal of Functional Programming, 2006.<br />
<br />
==Implicit parameters==<br />
<br />
;[http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/implicit.ps Implicit Parameters: Dynamic Scoping with Static Types]<br />
:Jeffrey Lewis, Mark Shields, Erik Meijer and John Launchbury. POPL'00. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. J. Funct. Program. 14(5): 489-502 (2004) <br />
<br />
;[http://www.cs.uu.nl/pub/RUU/CS/techreps/CS-2004/2004-059.pdf Explicit Implicit Parameters]<br />
:A. Dijkstra and S. D. Swierstra. UU-CS 2004-059, 2004.<br />
<br />
==Object oriented Haskell==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] <br />
:Mark Shields and Simon Peyton Jones; BABEL workshop '01.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/PC03.html Interfacing Haskell with Object-Oriented Languages]<br />
:Andr T. H. Pang and Manuel M. T. Chakravarty. In Greg Michaelson and Phil Trinder, editors, Implementation of Functional Languages: 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, LNCS 3145, Springer-Verlag, pages 20-36, 2004. <br />
<br />
;[ftp://ftp.cs.chalmers.se/pub/cs-reports/papers/sparud/haskell++.ps.gz Haskell++: An Object-Oriented Extension of Haskell]<br />
:Jan Sparud and John Hughes. Haskell Workshop 1995<br />
<br />
;[http://homepages.cwi.nl/~ralf/OOHaskell/ Haskell's overlooked object system]<br />
:Oleg Kiselyov and Ralf Lämmel, submitted for journal publication; online since 30 Sep. 2004;<br />
<br />
==Restricted Datatypes==<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Papers/restricted-datatypes.ps Restricted datatypes]<br />
:John Hughes. 1999 Haskell workshop<br />
<br />
==Patterns==<br />
<br />
;[http://www.cs.yale.edu/homes/tullsen/patterns.ps First Class Patterns]<br />
:Mark Tullsen. Practical Aspects of Declarative Languages, Second International Workshop, PADL 2000. volume 1753 of Lecture Notes in Computer Science. January 2000. <br />
<br />
===Pattern guards===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/pat.htm Pattern Guards and Transformational Patterns]<br />
:Martin Erwig and Simon Peyton Jones; Haskell Workshop 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Haskell/guards.html A new view of guards]<br />
:Simon Peyton Jones, April 1997<br />
<br />
===Views===<br />
<br />
;[http://www.haskell.org/development/views.html Views: An Extension to Haskell Pattern Matching]<br />
:Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson and Phil Wadler.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps.gz Views: A way for pattern matching to cohabit with data abstraction]<br />
:POPL 14 (1987), 307-313.<br />
<br />
==Qualified types==<br />
<br />
;[http://haskell.readscheme.org/servlets/cite.ss?pattern=mpj-jones1994a Qualified Types: Theory and Practice]<br />
:Mark P. Jones. PhD. Thesis. Yale University. November 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca95.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. FPCA '95: Conference on Functional Programming Languages and Computer Architecture. June 1995.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-1040.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-1040. June 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-989.ps Coherence for qualified types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-989. September 1993. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/rev-qual-types.ps A theory of qualified types]<br />
:Mark P. Jones. ESOP '92: European Symposium on Programming. Lecture Notes in Computer Science, 582. February 1992. (Cited by 68)<br />
<br />
==Polymorphic recursion==<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D169692 Type inference with polymorphic recursion]<br />
:F Henglein - ACM Transactions on Programming Languages and Systems (1993)<br />
<br />
;[http://www.jucs.org/jucs_9_8/practical_type_inference_for/paper.pdf Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell]<br />
:C Vasconcellos, L Figueiredo, C Camarao - Journal of Universal Computer Science, 2003<br />
<br />
;[http://www.dcc.ufmg.br/~camarao/ml0-impl.ps Type Inference for Polymorphic Recursive Definitions: a Specification in Haskell]<br />
:L Figueiredo, C Camarao<br />
<br />
[[Category:Research]]<br />
[[Category:Type-level programming]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Type_systems&diff=16860Research papers/Type systems2007-11-15T02:32:44Z<p>Tschrijvers: </p>
<hr />
<div>__TOC__<br />
<br />
==Haskell semantics==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/static-semantics.dvi.gz A static semantics for Haskell]<br />
:SL Peyton Jones and PL Wadler, (draft), Department of Computing Science, University of Glasgow, 1992. (Cited by 20)<br />
<br />
;[http://haskell.org/onlinereport/dynamic-semantics.dvi.gz A Dynamic Semantics for Haskell] <br />
:Kevin Hammond and Cordelia Hall, (draft), University of Glasgow, 1992, 23 pages.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/thih.html Typing Haskell in Haskell] <br />
:Mark P. Jones, In Proceedings of the 1999 Haskell Workshop, Paris, France, October 1999. Published in Technical Report UU-CS-1999-28, Department of Computer Science, University of Utrecht. (Cited by 66)<br />
<br />
;[http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne/haskell_libs/hsparser.html HParser]<br />
:A parser for Haskell written purely in Haskell (using the Happy parser generator).<br />
<br />
;[http://www.cse.ogi.edu/~hallgren/Talks/LHiH/ A Lexer for Haskell in Haskell]<br />
:Thomas Hallgren, PacSoft Oregon Graduate Institute, 14 January, 2002<br />
<br />
;[http://citeseer.ist.psu.edu/launchbury93natural.html A Natural Semantics for Lazy Evaluation]<br />
:John Launchbury, Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, 144--154, 1993.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/papers/11.ps A Space Semantics for Core Haskell]<br />
:Adam Bakewell. Proc. 2000 Haskell Workshop. September 2001.<br />
<br />
==Pure type systems==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/henk.ps.gz Henk: a typed intermediate language]<br />
:SL Peyton Jones and E Meijer, Proceedings of the Types in Compilation Workshop, Amsterdam, June 1997.<br />
<br />
;[http://www.cs.uu.nl/~johanj/MSc/jwroorda/ Pure Type Systems for Functional Programming]<br />
:Jan-Willem Roorda, Masters Thesis, University of Utrecht, INF/SCR-00-13, available online, 2000<br />
<br />
==Dependent Types==<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/ydtm.pdf Why Dependent Types Matter]<br />
:Thorsten Altenkirch and Conor McBride and James McKinna, Manuscript, available online, April, 2005. (Cited by 7)<br />
<br />
;[http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html Simply Easy! An Implementation of a Dependently Typed Lambda Calculus]<br />
:Andres Löh, Conor McBride and Wouter Swierstra, 2007.<br />
<br />
==Unboxed values==<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z Unboxed values as first class citizens]<br />
:SL Peyton Jones and J Launchbury, Functional Programming Languages and Computer Architecture (FPCA'91), Boston, LNCS 523, Springer Verlag, Sept 1991, pp636-666. (Cited by 105)<br />
<br />
==Modules==<br />
<br />
;[http://www.cse.ogi.edu/~diatchki/papers/modules98.pdf A Formal Specification of the Haskell 98 Module System]<br />
:Iavor S. Diatchki, Mark P. Jones, and Thomas Hallgren. Proceedings of the 2002 ACM SIGPLAN workshop on Haskell. Pittsburgh, Pennsylvania. 17 - 28 2002 ISBN 1-58113-605-6 (Cited by 12)<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/first-class-modules/index.htm First class modules for Haskell]<br />
:Mark Shields and Simon Peyton Jones; FOOL'02.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/Nicklisch-modules.ps.gz An exploration of modular programs]<br />
:Electronic proceedings of the 1996 Glasgow Functional Programming Workshop, J Nicklisch and SL Peyton Jones, Ullapool, July 1996.<br />
<br />
==Exceptions==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf An Extensible Dynamically-Typed Hierarchy of Exceptions]<br />
:Simon Marlow. Haskell '06: Proceedings of the 2006 ACM SIGPLAN workshop on Haskell, Portland, Oregon, ACM Press, September 2006<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn-sem.htm Imprecise Exceptions, Co-Inductively]<br />
:Andy Moran, Soeren Lassen, and Simon Peyton Jones. HOOTS'99.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm A semantics for imprecise exceptions]<br />
:Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Language Design and Implementation (PLDI'99), Atlanta.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm Asynchronous exceptions in Haskell]<br />
:Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy, PLDI'01.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/except6.ps.gz Handling Exceptions in Haskell]<br />
:A. Reid, Research Report YALEU/DCS/RR-1175, Yale University, August, 1998<br />
<br />
==Lexically scoped type variables==<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/papers/scoped%2Dtyvars/ Lexically scoped type variables]<br />
:Simon Peyton Jones and Mark Shields. 2004.<br />
<br />
==Records==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
:Mark Jones and Simon Peyton Jones, Haskell Workshop 1999.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/scopedlabels.pdf Extensible records with scoped labels]<br />
:Daan Leijen. The 2005 Symposium on Trends in Functional Programming (TFP'05), Tallin, Estonia, September 2005.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/fclabels.pdf First-class labels for extensible rows]<br />
:Daan Leijen. Technical Report UU-CS-2004-51, Departement of Computer Science, Universiteit Utrecht, 2004.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/h-wkshop95a/index.html Haskell Records]<br />
:J. Peterson, A. Reid, Proceedings of the Haskell Workshop, La Jolla, June 1995. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/96-3.ps.gz A Polymorphic Type System for Extensible Records and Variants]<br />
:Benedict R. Gaster and Mark P. Jones. Department of Computer Science, University of Nottingham. Technical report NOTTCS-TR-96-3. November 1996.<br />
<br />
==Meta programming==<br />
<br />
;[http://research.microsoft.com/copyright/accept.asp?path=/users/simonpj/papers/dyntyping.ps.gz&pub=ACM Dynamic typing as staged type inference]<br />
:MB Shields, T Sheard, and SL Peyton Jones, POPL98.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/meta-haskell/index.htm Template meta-programming for Haskell]<br />
:Tim Sheard and Simon Peyton Jones, Proceedings of the Haskell Workshop, Pittsburgh, 2002<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCK04.html Optimising Embedded DSLs using Template Haskell]<br />
:Sean Seefried, Manuel M. T. Chakravarty, and Gabriele Keller. In Gabor Karsai and Eelco Visser, editors, Third International Conference on Generative Programming and Component Engineering (GPCE'04), LNCS 3286, Springer-Verlag, pages 186-205, 2004. [An earlier draft was presented at the IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, 2003.<br />
<br />
;[http://www.haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps Unrolling and Simplifying Expressions with Template Haskell]<br />
:Ian Lynagh, May 2003.<br />
<br />
;[http://www.haskell.org/th/papers/hlpp.ps Automatic skeletons in Template Haskell]<br />
:Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. Proceedings of 2003 Workshop on High Level Parallel Programming, Paris, France<br />
<br />
;[http://www.haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps Typing Template Haskell: Soft Types]<br />
:Ian Lynagh, August 2004.<br />
<br />
==Dynamic typing==<br />
<br />
;[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/BaSw02.bib Typing dynamic typing]<br />
:A. I. Baars and S. D. Swierstra. In S. Peyton Jones, editor, Proceedings of the seventh ACM SIGPLAN international conference on Functional programming, pages 157--166. ACM Press, 2002<br />
<br />
==Parametricity==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps.gz Theorems for free!]<br />
:Philip Wadler. 4'th International Conference on Functional Programming and Computer Architecture, London, September 1989.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/seqFinal.pdf The Impact of seq on Free Theorems-Based Program Transformations]<br />
:Patricia Johann and Janis Voigtländer, Fundamenta Informaticae, vol. 69(1-2), pp. 63-102, 2006.<br />
<br />
==Type classes==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz How to make ad-hoc polymorphism less ad hoc]<br />
:Philip Wadler and Stephen Blott. 16'th Symposium on Principles of Programming Languages, ACM Press, Austin, Texas, January 1989.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/classhask.ps.gz Type classes in Haskell, CV Hall, K Hammond, SL Peyton Jones, and PL Wadler]<br />
:European Symposium On Programming, LNCS 788, Springer Verlag, pp. 241-256, April 1994. (Cited by 131)<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/pldi93.html Implementing Type Classes]<br />
:John Peterson and Mark P. Jones, In Proceedings of ACM SIGPLAN Symposium on Programming Language Design and Implementation, ACM SIGPLAN, June 1993. (Cited by 40)<br />
<br />
;[http://www.cs.chalmers.se/pub/cs-reports/papers/overload-fpca-93.ps.Z Implementing Haskell overloading]<br />
:Lennart Augustsson, 1993. FPCA. 65-73<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/springschool.html Functional Programming with Overloading and Higher-Order Polymorphism]<br />
:Mark P. Jones, First International Spring School on Advanced Functional Programming Techniques, Baastad, Sweden, Springer-Verlag Lecture Notes in Computer Science 925, May 1995.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/type-class-design-space Type classes: exploring the design space]<br />
:Simon Peyton Jones, Mark Jones, Erik Meijer, Haskell Workshop 1997.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca93.html A system of constructor classes: overloading and implicit higher-order polymorphism]<br />
:Mark P. Jones, In FPCA '93: Conference on Functional Programming Languages and Computer Architecture, Copenhagen, Denmark, June 1993.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/overload2/overload2.ps.gz A second look at overloading]<br />
:Martin Odersky, Philip Wadler, Martin Wehr. 7'th International Conference on Functional Programming and Computer Architecture, ACM Press, San Diego, California, June 1995.<br />
<br />
;[http://citeseer.ist.psu.edu/laufer94combining.html Combining Type Classes and Existential Types]<br />
:Konstantin Laufer, Proceedings of the Latin American Informatic Conference (PANEL), 1994<br />
<br />
;[http://citeseer.ifi.unizh.ch/laeufer95type.html Type Classes with Existential Types]<br />
:Konstantin Laufer, Journal of Functional Programming, 1996, May<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/DHCK06.html Modular Type Classes]<br />
:Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty and Gabriele Keller, 2006<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/4.pdf Named instances for Haskell type classes]<br />
:W Kahl, J Scheffczyk - Proc. Haskell Workshop, 2001 (Cited by 12)<br />
<br />
===Deriving type classes===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/derive.htm Derivable Type classes] <br />
:Ralf Hinze and Simon Peyton Jones, Haskell Workshop 2000.<br />
<br />
;[http://www.cis.upenn.edu/~sweirich/RepLib/ RepLib: A Library for Derivable Type Classes]<br />
:Stephanie Weirich 2006<br />
<br />
===Applications of type classes===<br />
<br />
;[http://okmij.org/ftp/Haskell/number-parameterized-types.html Number-parameterized types]<br />
:Oleg Kiselyov, The Monad.Reader. IssueFive. Oct 2nd, 2005<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/typecase.pdf TypeCase: a design pattern for type-indexed functions]<br />
:Bruno C. d. S. Oliveira, Jeremy Gibbons. Proceedings of the 2005 ACM SIGPLAN workshop on Haskell. Tallinn, Estonia. 98 - 109, 2005 ISBN:1-59593-071-X<br />
<br />
;[http://okmij.org/ftp/Haskell/types.html#Prepose Functional pearl: implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan, Proceedings of the 2004 ACM SIGPLAN workshop on Haskell, Snowbird, Utah, USA, 2004 ISBN 1-58113-850-4<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/extract-typeclassproofs.pdf Extracting Programs from Type Class Proofs]<br />
:Martin Sulzmann, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/coind-type-class-proofs.ps Co-induction and Type Improvement in Type Class Proofs]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey. 2005<br />
<br />
;[http://www.cs.nott.ac.uk/~ctm/faking.ps.gz Faking It (Simulating Dependent Types in Haskell)]<br />
:Conor McBride, Journal of Functional Programming, 12(4&5):375-392, July 2002<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/aophaskell.ps.gz Aspect-Oriented Programming with Type Classes]<br />
:Martin Sulzmann and Meng Wang, 2006.<br />
<br />
==Undecidable instances==<br />
<br />
;[http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#undecidable-instances Undecidable instances]<br />
:GHC User's Guide.<br />
<br />
==Multi-parameter type classes==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/ghc-mptc-inf.ps Principal Type Inference for GHC-Style Multi-Parameter Type Classes]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey. In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/mptc-inf-old.pdf Type Inference for Multi-Parameter Type Classes]<br />
:Martin Sulzmann and Peter J. Stuckey. 2005<br />
<br />
;[http://ostrich.lcs.mit.edu/cgi-bin/pickbib?jfp::DugganO2002 Type-checking multi-parameter type classes]<br />
:Dominic Duggan and John Ophel, Journal of Functional Programming, 12(2):133-158, March 2002<br />
<br />
==Functional dependencies==<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fundeps.html Type Classes with Functional Dependencies]<br />
:Mark P. Jones, In Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/fd-chr/index.htm Sound and Decidable Type Inference for Functional Dependencies]<br />
:Gregory J. Duck, Simon Peyton Jones, Peter J. Stuckey, and Martin Sulzmann, European Symposium on Programming 2004 (ESOP'04).<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/jfp-fds-revised.pdf Understanding Functional Dependencies via Constraint Handling Rules]<br />
:Martin Sulzmann, Gregory J. Duck, Simon Peyton-Jones and Peter J. Stuckey.j To appear in Journal of Functional Programming. 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/afds.ps Associated Functional Dependencies]<br />
:Martin Sulzmann and Edmund Soon Lee Lam. 2005<br />
<br />
==Constraint Handling Rules==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/aplas06-invited.pdf Type Processing by Constraint Reasoning]<br />
:Peter J. Stuckey, Martin Sulzmann and Jeremy Wazny, In APLAS'06.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/chr-stm.ps A Concurrent Constraint Handling Rules Implementation in Haskell with Software Transactional Memory]<br />
:Edmund S.L. Lam and Martin Sulzmann<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/chr06-observable.ps Observable Confluence for Constraint Handling Rules]<br />
:Gregory J. Duck, Peter J. Stuckey and Martin Sulzmann<br />
<br />
==Generalised Algebraic Data Types (GADTs)==<br />
<br />
;[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs]<br />
:Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. Submitted to PLDI 2005<br />
<br />
;[http://www.cis.upenn.edu/~geoffw/research/papers/MS-CIS-05-26.pdf Wobbly types: type inference for generalised algebraic data types]<br />
:S Peyton Jones, G. Washburn, and S. Weirich. 2004.<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F]<br />
:Martin Sulzmann and Meng Wang. 2005<br />
<br />
;[http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types]<br />
:François Pottier and Yann Régis-Gianas, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/gadt-short.ps Type Inference for GADTs via Herbrand Constraint Abduction]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey, 2006 <br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/publications/tr-eadt.ps.gz A Framework for Extended Algebraic Data Types]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey, 2006<br />
<br />
See also the [[GADT]] page.<br />
<br />
==Parametric Regular Data Types==<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/parametric-regular.ps Type Inference and Compilation for Parametric Regular Data Types]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu, 2006<br />
<br />
;[http://www.comp.nus.edu.sg/~sulzmann/manuscript/haskell-xduce.ps The Marriage of Haskell and XDuce]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu<br />
<br />
==Associated types==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/assoc.pdf Associated types with class]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, Simon Marlow) POPL '05: Proceedings of the 32nd ACM SIGPLAN-SIGACT sysposium on Principles of programming languages, pages 1--13, Long Beach, California, USA, ACM Press, 2005<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming, ACM Press, pages 241-253, 2005.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/diplom ML Modules and Haskell Type Classes: A Constructive Comparison]<br />
:Stefan Wehr Diplomarbeit. Albert-Ludwigs-Universitt Freiburg, Fakultt fr Angewandte Wissenschaften, Institut fr Informatik, November 2005. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCP06.html System F with Type Equality Coercions]<br />
:Martin Sulzmann, Manuel M. T. Chakravarty, and Simon Peyton Jones.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/type_functions.pdf Towards Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Martin Sulzmann, and Manuel Chakravarty.<br />
In Proceedings of IFL' 07, Freiburg, Germany, 2007.<br />
<br />
<br />
==Arbitrary-rank polymorphism==<br />
<br />
;[http://www.ubka.uni-karlsruhe.de/vvv/1996/informatik/81/81.pdf.gz Putting type annotations to work]<br />
:Martin Odersky and Konstantin Läufer. Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. St. Petersburg Beach, Florida, United States. 54 - 67 1996 ISBN 0-89791-769-3<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext%3Ffulltextid%3D445910 Practical type inference for arbitrary-rank types]<br />
:SP Jones, M Shields - Submitted to the Journal of Functional Programming, 2005<br />
<br />
==Phantom types==<br />
<br />
;[http://techreports.library.cornell.edu:8081/Dienst/UI/1.0/Display/cul.cis/TR2003-1901 First-class phantom types]<br />
:James Cheney and Ralf Hinze. Technical Report TR2003-1901, Cornell University, 2003.<br />
<br />
;[http://ttic.uchicago.edu/~fluet/research/phantom-subtyping/jfp06/jfp06.pdf Phantom Types and Subtyping]<br />
:Matthew Fluet and Riccardo Pucella. Submitted to the Journal of Functional Programming, 2006.<br />
<br />
==Implicit parameters==<br />
<br />
;[http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/implicit.ps Implicit Parameters: Dynamic Scoping with Static Types]<br />
:Jeffrey Lewis, Mark Shields, Erik Meijer and John Launchbury. POPL'00. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. J. Funct. Program. 14(5): 489-502 (2004) <br />
<br />
;[http://www.cs.uu.nl/pub/RUU/CS/techreps/CS-2004/2004-059.pdf Explicit Implicit Parameters]<br />
:A. Dijkstra and S. D. Swierstra. UU-CS 2004-059, 2004.<br />
<br />
==Object oriented Haskell==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] <br />
:Mark Shields and Simon Peyton Jones; BABEL workshop '01.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/PC03.html Interfacing Haskell with Object-Oriented Languages]<br />
:Andr T. H. Pang and Manuel M. T. Chakravarty. In Greg Michaelson and Phil Trinder, editors, Implementation of Functional Languages: 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, LNCS 3145, Springer-Verlag, pages 20-36, 2004. <br />
<br />
;[ftp://ftp.cs.chalmers.se/pub/cs-reports/papers/sparud/haskell++.ps.gz Haskell++: An Object-Oriented Extension of Haskell]<br />
:Jan Sparud and John Hughes. Haskell Workshop 1995<br />
<br />
;[http://homepages.cwi.nl/~ralf/OOHaskell/ Haskell's overlooked object system]<br />
:Oleg Kiselyov and Ralf Lämmel, submitted for journal publication; online since 30 Sep. 2004;<br />
<br />
==Restricted Datatypes==<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Papers/restricted-datatypes.ps Restricted datatypes]<br />
:John Hughes. 1999 Haskell workshop<br />
<br />
==Patterns==<br />
<br />
;[http://www.cs.yale.edu/homes/tullsen/patterns.ps First Class Patterns]<br />
:Mark Tullsen. Practical Aspects of Declarative Languages, Second International Workshop, PADL 2000. volume 1753 of Lecture Notes in Computer Science. January 2000. <br />
<br />
===Pattern guards===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/pat.htm Pattern Guards and Transformational Patterns]<br />
:Martin Erwig and Simon Peyton Jones; Haskell Workshop 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Haskell/guards.html A new view of guards]<br />
:Simon Peyton Jones, April 1997<br />
<br />
===Views===<br />
<br />
;[http://www.haskell.org/development/views.html Views: An Extension to Haskell Pattern Matching]<br />
:Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson and Phil Wadler.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps.gz Views: A way for pattern matching to cohabit with data abstraction]<br />
:POPL 14 (1987), 307-313.<br />
<br />
==Qualified types==<br />
<br />
;[http://haskell.readscheme.org/servlets/cite.ss?pattern=mpj-jones1994a Qualified Types: Theory and Practice]<br />
:Mark P. Jones. PhD. Thesis. Yale University. November 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca95.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. FPCA '95: Conference on Functional Programming Languages and Computer Architecture. June 1995.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-1040.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-1040. June 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-989.ps Coherence for qualified types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-989. September 1993. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/rev-qual-types.ps A theory of qualified types]<br />
:Mark P. Jones. ESOP '92: European Symposium on Programming. Lecture Notes in Computer Science, 582. February 1992. (Cited by 68)<br />
<br />
==Polymorphic recursion==<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D169692 Type inference with polymorphic recursion]<br />
:F Henglein - ACM Transactions on Programming Languages and Systems (1993)<br />
<br />
;[http://www.jucs.org/jucs_9_8/practical_type_inference_for/paper.pdf Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell]<br />
:C Vasconcellos, L Figueiredo, C Camarao - Journal of Universal Computer Science, 2003<br />
<br />
;[http://www.dcc.ufmg.br/~camarao/ml0-impl.ps Type Inference for Polymorphic Recursive Definitions: a Specification in Haskell]<br />
:L Figueiredo, C Camarao<br />
<br />
[[Category:Research]]<br />
[[Category:Type-level programming]]</div>Tschrijvershttps://wiki.haskell.org/index.php?title=Research_papers/Authors&diff=16859Research papers/Authors2007-11-15T02:26:46Z<p>Tschrijvers: </p>
<hr />
<div>__NOTOC__<br />
<br />
==A==<br />
*[http://www.tcs.informatik.uni-muenchen.de/~abel/ Andres Abel]<br />
*[http://www.cs.nott.ac.uk/~txa/publ/ Thorsten Altenkirch]<br />
*[http://homepages.cwi.nl/~atanasso/pub Frank Atanassow]<br />
*[http://www.cs.chalmers.se/~augustss/ Lennart Augustsson]<br />
<br />
==B==<br />
*[http://www.cs.uu.nl/groups/ST/stbib/baars-by-year/baars-by-year-by-year.html Arthur Baars]<br />
*[http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications.html Richard Bird]<br />
*[http://www.cs.chalmers.se/~bjesse/ Per Bjesse]<br />
*[http://www.cs.chalmers.se/~boquist/ Urban Boquist]<br />
*[http://www.dcs.gla.ac.uk/~bunkenba/ Alex Bunkenburg]<br />
*[http://www.cs.sfu.ca/people/Faculty/Burton/publications.html F. Warren Burton]<br />
<br />
==C==<br />
*[http://www.cse.ogi.edu/~magnus/ Magnus Carlsson]<br />
*[http://www.cse.unsw.edu.au/~chak/papers/papers.html Manuel M. T. Chakravarty]<br />
*[http://www.cs.kent.ac.uk/people/staff/oc/pubs.html Olaf Chitil]<br />
*[http://www.iis.sinica.edu.tw/~trc/node2.html Tyng-Ruey Chuang]<br />
*[http://www.cs.chalmers.se/~koen/pubs/ Koen Claessen]<br />
*[http://www.dcs.gla.ac.uk/~grmc/ Graham Collins]<br />
*[http://www.irisa.fr/EXTERNE/projet/lande/consel/consel.html Charles Consel]<br />
*[http://www.apocalypse.org/pub/u/antony/work/index.html Antony Courtney]<br />
<br />
==D==<br />
*[http://www.c3.lanl.gov/~kei/publications.html Kei Davis]<br />
*[http://www.cse.ogi.edu/~diatchki/papers/ Iavor Diatchki]<br />
<br />
==E==<br />
*[http://conal.net/papers/ Conal Elliott]<br />
*[http://www.cambridge.intel-research.net/~rennals/ Robert Ennals]<br />
*[http://web.engr.oregonstate.edu/~erwig/papers/ Martin Erwig]<br />
<br />
==F==<br />
*[http://web.it.kth.se/~kff/publications.html Karl-Filip Fax&eacute;n]<br />
*[http://yeats.ucc.ie/~abf/ Alex Ferguson]<br />
*[http://www.galois.com/~sof/pubs.html Sigbjorn Finne]<br />
*[http://www.cs.uu.nl/people/jeroen/ Jeroen Fokker]<br />
<br />
==G==<br />
*[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/ Jeremy Gibbons]<br />
*[http://www.gill-warbington.com/home/andy/ Andy Gill]<br />
*[http://www.dcs.gla.ac.uk/~joy/ Joy Goodman]<br />
*[http://research.microsoft.com/~adg/ Andrew D. Gordon]<br />
*Louis-Julien Guillemette<br />
*[http://www.cs.chalmers.se/~gustavss/ J&ouml;rgen Gustavsson]<br />
<br />
==H==<br />
*[http://www.dcs.gla.ac.uk/~cvh/ Cordelia Hall]<br />
*[http://www.cse.ogi.edu/~hallgren/ Thomas Hallgren]<br />
*[http://www-fp.dcs.st-and.ac.uk/~kh/papers/ABSTRACTS.html Kevin Hammond]<br />
*[http://research.microsoft.com/~tharris/ Tim Harris]<br />
*[http://www.cs.uu.nl/~bastiaan/ Bastiaan Heeren]<br />
*[http://www.cs.chalmers.se/~heldal/ Rogardt Heldal]<br />
*[http://www.cs.unc.edu/~heringto/ Dean Herington]<br />
*[http://www.infosun.fmi.uni-passau.de/cl/staff/herrmann/index.html Christoph A. Herrmann]<br />
*[http://www.informatik.uni-bonn.de/~ralf/publications/ Ralf Hinze]<br />
*[http://www.cs.uu.nl/people/stefan Stefan Holdermans]<br />
*[http://www.cse.ogi.edu/~hook/new/Default.htm James Hook]<br />
*[http://www.ipl.t.u-tokyo.ac.jp/~hu/pub/tech.html Zhenjiang Hu]<br />
*[http://cs-www.cs.yale.edu/homes/hudak.html Paul Hudak]<br />
*[http://www.cs.chalmers.se/~rjmh/pubs.htm John Hughes]<br />
*[http://www.cs.nott.ac.uk/~gmh/ Graham Hutton]<br />
<br />
==I==<br />
*[http://www.cs.nott.ac.uk/Department/Staff/gmh/bib.html Graham Hutton]<br />
*[http://www.cs.uu.nl/groups/ST/stbib/ijzendoorn-by-year/ijzendoorn-by-year-by-year.html Arjan van IJzendoorn]<br />
*[http://www.cs.chalmers.se/~indrika/ Mia Indrika]<br />
<br />
==J==<br />
*[http://www.cs.chalmers.se/~patrikj/ Patrik Jansson]<br />
*[http://www.cs.uu.nl/groups/ST/stbib/jeuring-by-year/jeuring-by-year-by-year.html Johan Jeuring]<br />
*[http://crab.rutgers.edu/~pjohann/vita.html Patricia Johann]<br />
*[http://www.cs.chalmers.se/~bengtj/ Bengt Johansson]<br />
*[http://www.cs.chalmers.se/~johnsson Thomas Johnsson]<br />
*[http://web.cecs.pdx.edu/~mpj/pubs.html Mark P. Jones]<br />
*[http://www.cs.stir.ac.uk/~sbj/ Simon B. Jones]<br />
*[http://research.microsoft.com/Users/simonpj Simon Peyton Jones]<br />
*[http://www.syntaxpolice.org/ Isaac Jones]<br />
<br />
==K==<br />
*[http://users.info.unicaen.fr/~karczma Jerzy Karczmarczuk]<br />
*[http://www.cse.unsw.edu.au/~keller/#publications Gabriele Keller]<br />
*[http://okmij.org/ftp/ Oleg Kiselyov]<br />
*[http://www.cse.ogi.edu/~krstic/ Sava Krstic]<br />
<br />
==L==<br />
*[http://lsi.uniovi.es/~labra Jose E. Labra]<br />
*[http://homepages.cwi.nl/~ralf/publications.html Ralf Lämmel]<br />
*[http://www.cse.ogi.edu/~jl John Launchbury]<br />
*[http://www.cs.uu.nl/~daan/pubs.html Daan Leijen]<br />
*[http://www.cse.ogi.edu/~jlewis Jeff Lewis]<br />
*[http://www.seas.upenn.edu/~lipeng/homepage/ Peng Li]<br />
*[http://java.sun.com/people/sl/ Sheng Liang]<br />
*[http://www.iai.uni-bonn.de/~loeh Andres L&ouml;h]<br />
*[http://www.dcs.gla.ac.uk/~hwloidl/ Hans-Wolfgang Loidl]<br />
*[http://www.mathematik.uni-marburg.de/~loogen Rita Loogen]<br />
*[http://www.frogsonice.com/work.html Sandra J. Loosemore]<br />
*[http://web.comlab.ox.ac.uk/oucl/work/ian.lynagh/papers/ Ian Lynagh]<br />
<br />
==M==<br />
*[http://www.haskell.org/~simonmar/bib/bib.html Simon Marlow] <br />
*[http://www.cs.nott.ac.uk/~ctm/publications.html Conor McBride]<br />
*[http://www.dcs.st-andrews.ac.uk/~james/ James McKinna]<br />
*[http://www.kestrel.edu/home/people/meertens/ Lambert Meertens]<br />
*[http://research.microsoft.com/~emeijer/ Eric Meijer]<br />
*[http://www.engr.uconn.edu/~jeffm/ Jeff Meunier]<br />
*[http://www-users.cs.york.ac.uk/~ndm/downloads.php Neil Mitchell]<br />
*[http://www.disi.unige.it/person/MoggiE/publications.html Eugenio Moggi]<br />
*Andrew Moran<br />
*Stefan Monnier<br />
<br />
==N==<br />
*[http://cs-www.cs.yale.edu/homes/nilsson/papers.html Henrik Nilsson]<br />
*[http://www.cse.ogi.edu/~nordin Thomas Nordin]<br />
*[http://www.cse.ogi.edu/~nordland/ Johan Nordlander]<br />
<br />
==O==<br />
*[http://lampwww.epfl.ch/~odersky/papers/ Martin Odersky]<br />
*[http://www.dcs.gla.ac.uk/~jtod/ John O'Donnell]<br />
*[http://www.eecs.usma.edu/Personnel/okasaki Chris Okasaki]<br />
*[http://www.ipl.t.u-tokyo.ac.jp/~onoue/ Yoshiyuki Onoue]<br />
<br />
==P==<br />
*[http://www.cs.chalmers.se/~pareto/ Lars Pareto]<br />
*[http://www.dcs.gla.ac.uk/~partain/ Will Partain]<br />
*[http://www.soi.city.ac.uk/~ross/papers/ Ross Paterson]<br />
*[[User:John Peterson|John Peterson]]<br />
*[http://research.microsoft.com/Users/simonpj Simon Peyton Jones]<br />
*[http://www.cs.mu.oz.au/~bjpop/papers.html Bernie Pope]<br />
*[http://www.mathematik.uni-marburg.de/~priebe Steffen Priebe]<br />
<br />
==Q==<br />
<br />
==R==<br />
*[http://www.reid-consulting-uk.ltd.uk/alastair/ Alastair Reid]<br />
*[http://www.dcs.gla.ac.uk/~reidrm/ Richard Reid]<br />
*[http://www.dcs.gla.ac.uk/~reig/ Fermin Reig]<br />
*[http://www-users.cs.york.ac.uk/~colin/ Colin Runciman]<br />
<br />
==S==<br />
*[http://www.cs.chalmers.se/~andrei/ Andrei Sabelfeld]<br />
*[http://www.dcs.gla.ac.uk/~meurig/ Meurig Sage]<br />
*[http://www.cs.chalmers.se/~dave/ David Sands]<br />
*[http://www.dcs.gla.ac.uk/~sansom/ Patrick Sansom]<br />
*[http://www.di.ufpe.br/~alms/ Andr&eacute; Santos]<br />
*[http://www.cs.kuleuven.be/~toms/ Tom Schrijvers]<br />
*[http://www.cse.unsw.edu.au/~sseefried/papers/papers.html Sean Seefried]<br />
*[http://web.cecs.pdx.edu/~sheard/papers/ Tim Sheard]<br />
*[http://www.cs.chalmers.se/~ms/ Mary Sheeran]<br />
*[http://www.cse.ogi.edu/~mbs/ Mark Shields]<br />
*[http://www.dis.strath.ac.uk/people/sinclair/ Duncan Sinclair]<br />
*[http://www.xilinx.com/labs/satnam Satnam Singh]<br />
*[http://www.cs.chalmers.se/~sparud/ Jan Sparud]<br />
*[http://www.cs.bris.ac.uk/~spilio/ Eleni Spiliopoulou]<br />
*[http://www.cse.unsw.edu.au/~dons/papers.html Don Stewart]<br />
*[http://www.comp.nus.edu.sg/~sulzmann/ Martin Sulzmann]<br />
*[http://www.cs.chalmers.se/~josefs/ Josef Svenningsson]<br />
*[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/swierstra-by-year-by-year.html Doaitse Swierstra]<br />
<br />
==T==<br />
*[http://www.cs.chalmers.se/~makoto Makoto Takeyama]<br />
*[http://www.math.uni-bremen.de/~thielema/ResearchE.html Henning Thielemann]<br />
*[http://www.cs.kent.ac.uk/people/staff/sjt/pubs.html Simon Thompson]<br />
*[http://www.cs.york.ac.uk/~mjt/ Michael Thyer]<br />
*[http://www.macs.hw.ac.uk/~trinder/publications.html Paul Trinder]<br />
*[http://www.cs.yale.edu/homes/tullsen/publications.html Mark Tullsen]<br />
<br />
==U==<br />
<br />
* [http://www.cs.ioc.ee/~tarmo/papers/ Tarmo Uustalu]<br />
<br />
==V==<br />
* [http://www.cs.ru.nl/A.vanWeelden/index.php?p=publications Arjen van Weelden]<br />
* [http://www.cs.ut.ee/~varmo/papers/index.html Varmo Vene]<br />
* [http://wwwtcs.inf.tu-dresden.de/~voigt/ Janis Voigtländer]<br />
<br />
==W==<br />
*[http://homepages.inf.ed.ac.uk/wadler/ Philip Wadler]<br />
*[ftp://ftp.cs.york.ac.uk/pub/malcolm/ Malcolm Wallace]<br />
*[http://www.lochan.org/keith/publications/index.html Keith Wansbrough]<br />
*[http://www.cis.upenn.edu/~geoffw/research/index.html Geoff Washburn]<br />
*[http://www.seas.upenn.edu/%7Esweirich/publications.html Stephanie Weirich]<br />
*[http://www.informatik.uni-freiburg.de/~wehr/#Publications Stefan Wehr]<br />
*[http://www.lotus.com/lotus/research.nsf/grouppage?Openpage Eric Wilcox]<br />
*[http://www.dcs.gla.ac.uk/~nww/ Noel Winstanley]<br />
<br />
==X==<br />
*[http://www.cl.cam.ac.uk/~nx200/ Dana Xu]<br />
<br />
==Y==<br />
<br />
==Z==<br />
<br />
<i>Authors, please add yourself! :)</i></div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13225GHC/Type families2007-05-25T14:11:44Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
Type family instance declarations are only legitimate when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
type family T a<br />
type instance T Int = A<br />
type instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
It might seem as if a definition, such as the above, should be feasible. However, type families are are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different type instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a type family used in a single program may not overlap at all, independent of whether they are associated or not. This is not only a matter of consistency, but one of type safety.<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13224GHC/Type families2007-05-25T13:41:21Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
Type family instance declarations are only legitimate when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
type family T a<br />
type instance T Int = A<br />
type instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
It might seem as if a definition, such as the above, should be feasible. However, type families are are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different type instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13221GHC/Type families2007-05-25T10:39:40Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
Type family instance declarations are only legitimate when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13220GHC/Type families2007-05-25T10:36:35Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13219GHC/Type families2007-05-25T10:33:53Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13218GHC/Type families2007-05-25T09:36:16Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>tom.schrijvers@cs.kuleuven.be</tt>.]<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Named arguments are _not_ optional.<br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13217GHC/Type families2007-05-25T08:32:22Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types ar much better behaved than<br />
functional dependencies. Hence, GHC's type checking and inference are<br />
more powerful. Here is an example of how to port your existing functional <br />
depenency programs to associated type synonyms.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13216GHC/Type families2007-05-25T08:24:26Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13215GHC/Type families2007-05-25T08:22:07Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollect :: (Collects e c1,Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollect :: (Collects c1,Collects c2,Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
<br />
== Open issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13210GHC/Type families2007-05-24T17:02:50Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
=== The Class Declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An Instance ===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
</haskell><br />
<br />
With associated type synonyms, this becomes:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
</haskell><br />
<br />
<br />
<br />
== Open Issues ==<br />
<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13209GHC/Type families2007-05-24T17:01:18Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
=== The Class Declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An Instance ===<br />
<br />
Here's an instance, with functional dependencies:<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) | e == x = True<br />
| otherwise = member e xs<br />
</haskell><br />
<br />
<br />
<br />
== Open Issues ==<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13208GHC/Type families2007-05-24T16:57:29Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
=== The Class Declaration ===<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
=== An Instance ===<br />
<br />
TODO<br />
<br />
<br />
== Open Issues ==<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13207GHC/Type families2007-05-24T16:56:17Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</hask>.<br />
<br />
== Open Issues ==<br />
<br />
None.</hask></div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13206GHC/Type families2007-05-24T16:55:52Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
With associated type synonyms we can write this as:<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
</haskell><br />
That's right, we have dropped from a multi-paramter type class<br />
to a single parameter type class. The parameter <hask>e</hask><br />
has become an associated type <hask>Elem ce</e>.<br />
<br />
== Open Issues ==<br />
<br />
None.</hask></div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13205GHC/Type families2007-05-24T16:53:46Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
<br />
== A associated type synonym example ==<br />
<br />
Associated data types are a better alternative for the rather complicated<br />
functional dependencies.<br />
<br />
Here's an example from the original Functional Dependencies paper:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
</haskell><br />
<br />
== Open Issues ==<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13204GHC/Type families2007-05-24T16:48:10Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Data and type families in GHC ==<br />
<br />
Data and type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that type families (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use <hask>data</hask> families.<br />
<br />
== What do I need to use data families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== Open Issues ==<br />
<br />
None.</div>Tschrijvershttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=13203GHC/Type families2007-05-24T16:39:46Z<p>Tschrijvers: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Type families in GHC ==<br />
<br />
Type families are a new addition to GHC's type extensions. They are currently an '''experimental''' feature and so their design may still change to some degree. The current implementation covers ''data families'' (including newtypes), which can either be on the toplevel or inside class declarations - the latter are also known as [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types]. <br />
<br />
'''NB:''' Please note that indexed type ''synonyms'' (and hence also associated type synonyms) are '''not''' fully implemented yet. Any attempt to use them will lead to strange error messages. For the moment, you can only use indexed <hask>data</hask> families.<br />
<br />
== What do I need to use indexed type families? ==<br />
<br />
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-ftype-families</tt> (or <tt>-fglasgow-exts</tt>, which implies it). NB: The option used to be called <tt>-findexed-types</tt> for a while.<br />
<br />
== An example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundemental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Nest, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and quering a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Definition of the type system extension ==<br />
<br />
['''NB:''' The following material will eventually become documentation for type families in the GHC User Manual. Please help to improve it by forwarding suggestions to <tt>chak@cse.unsw.edu.au</tt>.]<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the later can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrieved example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
If kind signatures are required for argument variables, they need to be given in the class head.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsence :: T a -> Int<br />
nonsence A = 1 -- WRONG: These two equations together...<br />
nonsence B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Class instances of type instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implcitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== Open Issues ==<br />
<br />
None.</div>Tschrijvers