https://wiki.haskell.org/api.php?action=feedcontributions&user=Dreixel&feedformat=atomHaskellWiki - User contributions [en]2020-08-04T20:41:28ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=Haskell_in_industry&diff=59018Haskell in industry2014-10-20T14:38:08Z<p>Dreixel: Add Chordify</p>
<hr />
<div>__NOTOC__<br />
<br />
Haskell has a diverse range of use commercially, from aerospace and defense, to finance, to web startups, hardware design firms and a lawnmower manufacturer. This page collects resources on the industrial use of Haskell.<br />
<br />
* The main user conference for industrial Haskell use is CUFP - the [http://cufp.org/ Commercial Users of Functional Programming Workshop].<br />
* The [http://industry.haskell.org Industrial Haskell Group] supports commercial users.<br />
* [http://fpcomplete.com/ FP Complete] is dedicated to the widespread adoption of modern Functional Programming technology, with a focus on the Haskell system. See their collection of [https://www.fpcomplete.com/page/case-studies case studies] of successes in commercial use.<br />
<br />
== Haskell in Industry ==<br />
<br />
Many companies have used Haskell for a range of projects, including:<br />
<br />
* [http://cufp.galois.com/2007/abstracts.html#CyrilSchmidt ABN AMRO] Amsterdam, The Netherlands<br />
<blockquote><br />
ABN AMRO is an international bank headquartered in Amsterdam. For its<br />
investment banking activities it needs to measure the counterparty risk<br />
on portfolios of financial derivatives. </blockquote><br />
::ABN AMRO's [http://cufp.galois.com/2007/abstracts.html#CyrilSchmidt CUFP talk].<br />
<br />
* Aetion Technologies LLC, Columbus, Ohio<br />
<blockquote><br />
Aetion was a defense contractor in operation from 1999 to 2011, whose applications use artificial intelligence. Rapidly changing priorities make it important to minimize the code impact of changes, which suits Haskell well. Aetion developed three main projects in<br />
Haskell, all successful. Haskell's concise code was perhaps most important for<br />
rewriting: it made it practicable to throw away old code occasionally. DSELs<br />
allowed the AI to be specified very declaratively. <br />
</blockquote><br />
::Aetion's [http://cufp.galois.com/2006/slides/GaryMorris.pdf CUFP talk].<br />
<br />
* Alcatel-Lucent<br />
<blockquote><br />
A consortium of groups, including Alcatel-Lucent, have used Haskell to prototype narrowband software radio systems, running in (soft) real-time.<br />
</blockquote><br />
::Alcatel-Lucent's [http://cufp.org/conference/sessions/2011/fourteen-days-haskell-real-time-programming-projec CUFP talk]<br />
<br />
* [http://www.allstontrading.com/ Allston Trading]<br />
<blockquote><br />
Headquartered in Chicago, Illinois, Allston Trading, LLC is a premier high frequency market maker in over 40 financial exchanges, in 20 countries, and in nearly every conceivable product class. Allston makes some use of Haskell for their trading infrastructure.<br />
</blockquote><br />
<br />
* [http://www.alphaheavy.com/ Alpha Heavy Industries]<br />
<blockquote><br />
Alpha Heavy Industries is an alternative asset manager dedicated to producing superior returns through quantitative methods. They use Haskell as their primary implementation language.<br />
</blockquote><br />
<br />
* [http://www.amgen.com/ Amgen] Thousand Oaks, California<br />
<blockquote><br />
Amgen is a human therapeutics company in the biotechnology industry. Amgen pioneered the development of novel products based on advances in recombinant DNA and molecular biology and launched the biotechnology industry’s first blockbuster medicines.<br />
<br />
Amgen uses Haskell;<br />
<br />
* To rapidly build software to implement mathematical models and other complex, mathematically oriented applications<br />
* Provide a more mathematically rigorous validation of software<br />
* To break developers out of their software development rut by giving them a new way to think about software.<br />
</blockquote><br />
::Amgen's [http://cufp.galois.com/2008/abstracts.html#BalabanDavid CUFP talk].<br />
<br />
* [http://www.ansemond.com/ Ansemond LLC]<br />
<blockquote><br />
"Find It! Keep It! is a Mac Web Browser that lets you keep the pages you<br />
visit in a database. A list of these pages is shown in the 'database<br />
view'. "<br />
</blockquote><br />
<br />
* [http://antiope.com/ Antiope] Fair Haven, New Jersey<br />
<blockquote><br />
Antiope Associates provides custom solutions for wireless communication<br />
and networking problems. Our team has expertise in all aspects of<br />
wireless system design, from the physical and protocol layers to complex<br />
networked applications. Antiope Associates relies on a number of<br />
advanced techniques to ensure that the communication systems we design<br />
are reliable and free from error. We use custom simulation tools<br />
developed in Haskell, to model our hardware designs..<br />
</blockquote><br />
::Antiope's [http://cufp.galois.com/2008/slides/WrightGregory.pdf CUFP talk].<br />
<br />
* [http://www.att.com AT&amp;T]<br />
<blockquote><br />
Haskell is being used in the Network Security division to automate processing of internet abuse complaints. Haskell has allowed us to easily meet very tight deadlines with reliable results.<br />
</blockquote><br />
<br />
* [http://www.baml.com/ Bank of America Merril Lynch]<br />
<blockquote>Haskell is being used for backend data transformation and loading.</blockquote><br />
<br />
* [http://www.haskell.org/communities/12-2007/html/report.html#sect7.1.2 Barclays Capital Quantitative Analytics Group]<br />
<blockquote><br />
Barclays Capital's Quantitative Analytics group is using Haskell to<br />
develop an embedded domain-specific functional language (called FPF)<br />
which is used to specify exotic equity derivatives. These derivatives,<br />
which are naturally best described in terms of mathematical functions,<br />
and constructed compositionally, map well to being expressed in an<br />
embedded functional language. This language is now regularly being used<br />
by people who had no previous functional language experience.<br />
</blockquote><br />
::[http://lambda-the-ultimate.org/node/3331 Simon Frankau et al's JFP paper on their use of Haskell]<br />
::[http://www.reddit.com/r/haskell/comments/1p70l3/barclays_are_hiring_haskell_developers_in_london/ Read their 2013 job advertisement]<br />
<br />
* BAE Systems<br />
<blockquote><br />
As part of the SAFE project, BAE has built a collection of compilers, interpreters, simulators, and EDSLs almost entirely in Haskell.<br />
</blockquote><br />
::[http://cufp.org/conference/sessions/2013/tom-hawkins-bae-systems-redesigning-computer-secur CUFP 2013 talk]<br />
<br />
* [http://bazqux.com BazQux Reader]<br />
<blockquote><br />
BazQux Reader is a commercial RSS reader. Its feeds and comments crawler and a part of web-server are implemented in Haskell.<br />
</blockquote><br />
<br />
* [http://better.com Better]<br />
<blockquote><br />
Better, formerly known as Erudify, is a learning company built around the mission of making people better. We are an unusual mix of a software company, a consulting firm, and a creative agency. This tight integration enables us to deliver innovative, high-quality courses to our customers.<br />
<br />
Founded in 2012, Better is based in Zurich, Switzerland and New York, USA. Better is fully invested in Haskell; Most parts of our back-end system (web-servers and learning logic) are written in Haskell. Haskell is also used in most parts of our front-end system. <br />
</blockquote><br />
<br />
* [http://www.bcode.com/ bCODE Pty Ltd] Sydney Australia<br />
<blockquote><br />
bCode Pty Ltd is a small venture capital-funded startup using Ocaml and a bit of Haskell in Sydney Australia.<br />
</blockquote><br />
<br />
* [http://bdellium.com/ Bdellium] Hawaii, United States<br />
<blockquote><br />
Bdellium develops software systems that enable companies in the financial industry to deliver new customer services that grow their business. Bdellium uses Haskell for heavy lifting analysis in back end infrastructure.<br />
</blockquote><br />
<br />
* [http://www.bluespec.com/ Bluespec, Inc.] Waltham, Massachusetts<br />
<br />
<blockquote><br />
Developing a modern integrated circuit (ASIC or FPGA) is an enormously<br />
expensive process involving specification, modeling (to choose and fix the<br />
architecture), design (to describe what will become silicon) and verification<br />
(to ensure that it meets the specs), all before actually committing anything to<br />
silicon (where the cost of a failure can be tens of millions of dollars).<br />
Bluespec, Inc. is a three year-old company that provides language facilities,<br />
methodologies, and tools for this purpose, within the framework of the IEEE<br />
standard languages SystemVerilog and SystemC, but borrowing ideas heavily from<br />
Term Rewriting Systems and functional programming languages like Haskell. In<br />
this talk, after a brief technical overview to set the context, we will<br />
describe our tactics and strategies, and the challenges we face, in introducing<br />
declarative programming ideas into this field, both externally (convincing<br />
customers about the value of these ideas) and internally (using Haskell for our<br />
tool implementation). <br />
</blockquote><br />
<br />
::Bluespec's [http://cufp.galois.com/2006/abstracts.html#RishiyurNikhil CUFP talk].<br />
<br />
* [http://bu.mp/ Bump]<br />
<blockquote><br />
Bump use a Haskell-based server, [http://github.com/jamwt/Angel Angel], for process supervisor for all their backend systems, and [http://devblog.bu.mp/post/40786229350/haskell-at-bump for other infrastructure tasks].<br />
</blockquote><br />
::Haskell at [http://fpcomplete.com/downloads/bump-fp-complete-study.pdf Bump]<br />
<br />
* Capital IQ<br />
<blockquote><br />
We have been using functional programming here at S&P Capital IQ in Scala, Haskell, and our homegrown reporting language Ermine, since 2008 for financial analytics.<br />
</blockquote><br />
::[http://cufp.org/conference/sessions/2013/edward-kmett-sp-capital-iq-functional-reporting Capital IQ's CUFP 2013 talk]<br />
<br />
* [http://chordify.net Chordify]<br />
<blockquote><br />
Chordify is a free online music service that transforms music, from YouTube, Deezer, SoundCloud or uploaded files, into chords. There's an ICFP experience report explaining how Haskell is used for this:<br />
<br />
José Pedro Magalhães and W. Bas de Haas. [http://dreixel.net/research/pdf/fmmh.pdf Functional Modelling of Musical Harmony: an Experience Report]. In Proceedings of the 16th ACM SIGPLAN International Conference on Functional Programming (ICFP'11), pp. 156–162, ACM, 2011.<br />
</blockquote><br />
<br />
* [http://www.circos.com Circos Brand Karma] Singapore<br />
<blockquote><br />
Brand Karma provides services to brand owners to measure online sentiments towards their brands.<br />
Haskell is used in building parts of the product, specifically for back-end job scheduling and brand matching.<br />
</blockquote><br />
<br />
* [http://www.credit-suisse.com/ Credit Suisse Global Modeling and Analytics Group] London, UK; New York City, New York<br />
<br />
<blockquote><br />
GMAG, the quantitative modeling group at Credit Suisse, has been using Haskell<br />
for various projects since the beginning of 2006, with the twin aims of<br />
improving the productivity of modelers and making it easier for other people<br />
within the bank to use GMAG models. Current projects include: Further work on<br />
tools for checking, manipulating and transforming spreadsheets; a<br />
domain-specific language embedded in Haskell for implementing reusable<br />
components that can be compiled into various target forms (see the video presentation: [http://www.londonhug.net/2008/08/11/video-paradise-a-dsel-for-derivatives-pricing/ Paradise, a DSEL for Derivatives Pricing]).<br />
</blockquote><br />
<br />
::Credit Suisse's [http://cufp.galois.com/2006/abstracts.html#HowardMansell CUFP talk].<br />
<br />
* [http://detexify.kirelabs.org/classify.html Detexify]<br />
<br />
<blockquote><br />
Detexify is an online handwriting recognition system, whose backend is written in Haskell. <br />
</blockquote><br />
<br />
* [http://fynder.io Fynder]<br />
<blockquote><br />
Fynder is an online booking platform.<br />
<br />
We use Haskell and clojurescript, all stitched together with nixos<br />
</blockquote><br />
<br />
::See more in their original [http://hackerjobs.co.uk/jobs/2013/9/27/digital-logistics-haskell-developer job posting].<br />
<br />
* [http://www.db.com/ Deutsche Bank Equity Proprietary Trading, Directional Credit Trading]<br />
<br />
<blockquote><br />
The Directional Credit Trading group uses Haskell as the primary<br />
implementation language for all its software infrastructure.<br />
</blockquote><br />
<br />
::Deutsche Bank's [http://cufp.galois.com/2008/abstracts.html#PolakowJeff CUFP talk].<br />
<br />
* [http://article.gmane.org/gmane.comp.lang.haskell.cafe/37093 Eaton] Cleveland, Ohio<br />
<br />
<blockquote><br />
Design and verification of hydraulic hybrid vehicle systems<br />
</blockquote><br />
<br />
::Eaton's [http://cufp.galois.com/2008/abstracts.html#HawkinsTom CUFP talk]<br />
::Eaton's [http://www.haskell.org/pipermail/haskell-cafe/2009-April/060602.html experiences using a Haskell DSL]<br />
<br />
* [Ericsson AB]<br />
<blockquote><br />
Ericsson uses Haskell for the implementation of Feldspar, an EDSL for digital signal processing algorithms.<br />
</blockquote><br />
<br />
::Ericsson's [http://hackage.haskell.org/package/feldspar-compiler Feldspar compiler]<br />
<br />
* [http://facebook.com Facebook]<br />
<br />
<blockquote><br />
Facebook uses some Haskell internally for tools. [http://github.com/facebook/lex-pass/tree/master lex-pass] is a tool for programmatically manipulating a PHP code base via Haskell.<br />
</blockquote><br />
<br />
:: Facebook's [http://cufp.galois.com/2009/abstracts.html#ChristopherPiroEugeneLetuchy CUFP talk]<br />
:: Facebook's [http://skillsmatter.com/podcast/home/simon-marlow HaXL system] is [https://code.facebook.com/projects/854888367872565/haxl/ open source]<br />
<br />
* [http://www.factisresearch.com/ Factis Research]<br />
<blockquote><br />
Factis research, located in Freiburg, Germany, develops reliable and user-friendly mobile solutions. Our client software runs under J2ME, Symbian, iPhone OS, Android, and Blackberry. The server components are implemented in Python and Haskell. We are actively using Haskell for a number of projects, most of which are released under an open-source license.<br />
</blockquote><br />
<br />
:: Factis' [http://haskell.org/communities/05-2010/html/report.html#factisresearch HCAR submission]<br />
<br />
* [http://fortytools.com fortytools gmbh]<br />
<blockquote><br />
Located in Hamburg, Germany, we are developing web-based productivity tools for invoicing, customer management, resource scheduling and time tracking. While using Javascript for building rich frontend application in the browser, we use Haskell to implement the REST backends. Additionally, we do occasional project/client work as well.<br />
</blockquote><br />
<br />
:: Oh, and of course we develop and maintain [http://hayoo.info Hayoo!] :)<br />
<br />
<br />
* [http://www.functor.se/ Functor AB], Stockholm, Sweden<br />
<blockquote><br />
Functor AB offers new tools for ground-breaking static analysis with pre-test case generation of programs to eliminate defects and bugs in software very early in development. <br />
<br />
Functor collaborates with the JET fusion reactor run by EFDA CCFE. JET is currently the largest reactor in the world of its kind. At Functor, almost all development is done in Haskell but also to some extent also C and Scala.<br />
</blockquote><br />
<br />
:: See more in the Functor AB [http://alpmestan.com/posts/2012-10-23-haskell-job-opening-at-functor.html job advertisement]<br />
<br />
* [http://www.funktional.info/index.php?id=7&L=1 Funktionale Programmierung Dr. Heinrich Hördegen], Munich, Germany<br />
<blockquote><br />
We develop software prototypes according to the Pareto principle: After spending only 20 percent of budget, we aim to provide already 80 percent of the software's functionality. We can realize this by constructing a 2080-software-prototype that we can further develop into a full-fledged solution...<br />
</blockquote><br />
<br />
* [http://www.galois.com/ Galois, Inc] Portland, Oregon<br />
<br />
<blockquote><br />
Galois designs and develops high confidence software for critical applications.<br />
Our innovative approach to software development provides high levels of<br />
assurance, yet its scalability enables us to address the most complex problems.<br />
We have successfully engineered projects under contract for corporations and<br />
government clients in the demanding application areas of security, information<br />
assurance and cryptography. <br />
</blockquote><br />
<br />
::Galois' [http://cufp.galois.com/2007/abstracts.html#JohnLaunchbury 2007 CUFP talk]<br />
::Galois' [http://cufp.org/conference/sessions/2011/theorem-based-derivation-aes-implementation 2011 CUFP talk]<br />
::Galois' [http://corp.galois.com/blog/2009/4/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galo.html retrospective on 10 years of industrial Haskell use]<br />
<br />
* [http://google.com Google]<br />
<br />
<blockquote><br />
Haskell is used on a small number of internal projects in Google, for internal IT infrastructure support, and the open-source [http://code.google.com/p/ganeti/ Ganeti] project. Ganeti is a tool for managing clusters of<br />
virtual servers built on top of Xen and KVM.<br />
</blockquote><br />
<br />
::Google's [http://k1024.org/~iusty/papers/icfp10-haskell-reagent.pdf ICFP 2010 experience report on Haskell]<br />
::Video from ICFP [http://vimeo.com/12849320 Project Ganeti at Google]<br />
<br />
* [http://glyde.com/ Glyde]<br />
<br />
<blockquote><br />
Glyde uses OCaml and Haskell for a few projects. Glyde uses Haskell for our client-side template source-to-source translator, which converts HAML-like view templates into JS code.<br />
</blockquote><br />
<br />
* [http://groupcommerce.com Group Commerce]<br />
<blockquote><br />
Group Commerce uses Haskell to drive the main component of their advertising infrastructure: a Snap Framework based web server. Haskell enabled quicker development, higher reliability, and better maintainability than other languages, without having to sacrifice performance.<br />
</blockquote><br />
<br />
* [http://humane-software.com Humane Software]<br />
<blockquote>We develop enterprise systems with de-coupled, asynchronous Haskell backends and Javascript UIs.<br><br />
For our current customer, an Internet connectivity provider, we wrote a solution for monitoring multiple remote machines and analyzing gigabytes of traffic samples. Haskell proved an excellent tool for the job. <br />
We were able to replace legacy systems in a granular, piece-by-piece manner, while delivering new features.</blockquote><br />
<br />
* [http://hustlerturf.com Hustler Turf Equipment] Hesston, Kansas<br />
<blockquote><br />
Designs, builds, and sells lawn mowers. We use quite a bit of Haskell, especially as a "glue language" for tying together data from different manufacturing-related systems. We also use it for some web apps that are deployed to our dealer network. There are also some uses for it doing sysadmin<br />
automation, such as adding/removing people from LDAP servers and the like<br />
</blockquote><br />
<br />
* [http://iba-cg.de/haskell.html iba Consulting Gesellschaft] - Intelligent business architecture for you. Leipzig, Germany<br />
<br />
<blockquote><br />
iba CG develops software for large companies: <br />
* risk analysis and reporting solution for power supply company; <br />
* contract management, assert management, booking and budgeting software for one of the worldwide leading accounting firm.<br />
</blockquote><br />
<br />
* [http://www.imvu.com IMVU, Inc]<br />
<br />
<blockquote><br />
IMVU, Inc. is a social entertainment company connecting users through 3D avatar-based experiences. See the blog article [http://engineering.imvu.com/2014/03/24/what-its-like-to-use-haskell/ What it's like to use Haskell]<br />
</blockquote><br />
<br />
* [http://www.ics-ag.de/ Informatik Consulting Systems AG]<br />
<br />
<blockquote><br />
ICS AG developed a simulation and testing tool which based on a DSL (Domain Specific Language). The DSL is used for the description of architecture and behavior of distributed system components (event/message based, reactive). The compiler was written in Haskell (with target language Ada). The test system is used in some industrial projects.<br />
</blockquote><br />
<br />
* [http://intel.com Intel]<br />
<blockquote><br />
Intel has developed a Haskell compiler as part of their research on multicore parallelism at scale.<br />
</blockquote><br />
<br />
:: Read the Intel Research paper on [http://www.leafpetersen.com/leaf/publications/hs2013/hrc-paper.pdf compiler]<br />
<br />
* [http://www.ivu.de/uk/products/public-transport/ IVU Traffic Technologies AG]<br />
<blockquote><br />
The rostering group at IVU Traffic Technologies AG has been using Haskell to check rosters for compliance with EC regulations.<br />
<br />
Our implementation is based on an embedded DSL to combine the regulation’s single rules into a solver that not only decides on instances but, in the case of a faulty roster, finds an interpretation of the roster that is “favorable” in the sense that the error messages it entails are “helpful” in leading the dispatcher to the resolution of the issue at hand.<br />
<br />
The solver is both reliable (due to strong static typing and referential transparency — we have not experienced a failure in three years) and efficient (due to constraint propagation, a custom search strategy, and lazy evaluation).<br />
<br />
Our EC 561/2006 component is part of the IVU.crew software suite and as such is in wide-spread use all over Europe, both in planning and dispatch. So the next time you enter a regional bus, chances are that the driver’s roster was checked by Haskell.<br />
</blockquote><br />
<br />
* [http://www.janrain.com JanRain]<br />
<blockquote><br />
JanRain uses Haskell for network and web software. Read more about [http://www.janrain.com/blogs/haskell-janrain Haskell at JanRain] and in their [http://corp.galois.com/blog/2011/3/8/tech-talk-haskell-and-the-social-web.html tech talk at Galois]. JanRain's "[http://www.janrain.com/products/capture Capture]" user API product is built on Haskell's Snap webframework.<br />
</blockquote><br />
<br />
:: See Janrain's [http://corp.galois.com/blog/2011/4/22/tech-talk-video-haskell-and-the-social-web.html technical talk about their use of Snap]<br />
<br />
* [http://joyridelabs.de/game/ Joyride Laboratories]<br />
<br />
<blockquote><br />
Joyride Laboratories is an independent game development studio, founded in 2009 by Florian Hofer and Sönke Hahn. Their first game, "Nikki and the Robots" was released in 2011.<br />
</blockquote><br />
<br />
* [http://www.linspire.com/ Linspire]<br />
<br />
<blockquote><br />
Linspire, Inc. has used functional programming since its inception in 2001,<br />
beginning with extensive use of O'Caml, with a steady shift to Haskell as its<br />
implementations and libraries have matured. Hardware detection, software<br />
packaging and CGI web page generation are all areas where we have used<br />
functional programming extensively. Haskell's feature set lets us replace much<br />
of our use of little languages (e.g., bash or awk) and two-level languages (C<br />
or C++ bound to an interpreted language), allowing for faster development,<br />
better code sharing and ultimately faster implementations. Above all, we value<br />
static type checking for minimizing runtime errors in applications that run in<br />
unknown environments and for wrapping legacy programs in strongly typed<br />
functions to ensure that we pass valid arguments. <br />
</blockquote><br />
<br />
::Linspire's [http://cufp.galois.com/2006/abstracts.html#CliffordBeshers CUFP talk]<br />
::Linspire's experience report on using [http://portal.acm.org/citation.cfm?doid=1291151.1291184 functional programming to manage a Linux distribution]<br />
<br />
* [http://www.mitre.org/ MITRE]<br />
<blockquote><br />
MITRE uses Haskell for, amongst other things, the [http://hackage.haskell.org/package/cpsa analysis of cryptographic protocols].<br />
</blockquote><br />
<br />
* [http://nytimes.com The New York Times]<br />
<blockquote><br />
A team at the New York Times used Haskell's parallel array library to process images from 2013 New York Fashion Week. Haskell was chosen based on its fast numerical arrays packages, and ease of parallelization.<br />
</blockquote><br />
:: [http://source.mozillaopennews.org/en-US/articles/model-analysis/ Model analysis]<br />
:: [http://www.infoq.com/presentations/haskell-newsroom-nyt Haskell in the Newsroom]<br />
<br />
* [http://ertos.nicta.com.au/research/sel4/ NICTA]<br />
<blockquote><br />
NICTA has used Haskell as part of a project to verify the L4 microkernel.<br />
</blockquote><br />
::[http://www.drdobbs.com/embedded/222400553 Read the Dr. Dobbs article on using Haskell and formal methods to verify a kernel]<br />
<br />
* [http://www.gb.nrao.edu NRAO]<br />
<blockquote><br />
NRAO has used Haskell to implement the core science algorithms for the Robert C. Byrd Green Bank Telescope (GBT) Dynamic Scheduling System ([http://www.gb.nrao.edu/dss DSS]).<br />
::Source code available on [https://github.com/nrao/antioch GitHub].<br />
</blockquote><br />
<br />
* [http://www.ns-sol.co.jp NS Solutions(NSSOL)] Tokyo, Japan<br />
<blockquote><br />
NS Solutions has employed Haskell since 2008 to develop its software<br />
packages including "BancMeasure", a mark-to-market accounting software<br />
package for financial institutions, "BancMeasure for IFRS" and<br />
"Mamecif", a data analysis package.<br />
"BancMeasure" and "Mamecif" are registered trademarks of NS Solutions Corporation in JAPAN.<br />
</blockquote><br />
<br />
* [http://www.nvidia.com/content/global/global.php NVIDIA]<br />
<blockquote><br />
At NVIDIA, we have a handful of in-house tools that are written in Haskell<br />
</blockquote><br />
<br />
* [http://blog.openomy.com/2008/01/case-study-using-haskell-and-happs-for.html Openomy]<br />
<br />
<blockquote><br />
Openomy's API v2.0 is developed in Haskell, using the<br />
[http://www.happs.org/ HAppS] web platform.<br />
</blockquote><br />
<br />
* [http://www.oblomov.com Oblomov]<br />
<br />
<blockquote><br />
Oblomov Systems is a one-person software company based in Utrecht, The Netherlands. Founded in 2009, Oblomov has since then been working on a number of Haskell-related projects. The main focus lies on web-applications and (web-based) editors. Haskell has turned out to be extremely useful for implementing web servers that communicate with JavaScript clients or iPhone apps.<br />
</blockquote><br />
<br />
:: [http://haskell.org/communities/05-2010/html/report.html#oblomov Oblomov's HCAR submission].<br />
<br />
* [http://www.patch-tag.com Patch-Tag: hosting for Darcs]<br />
<blockquote><br />
Need somewhere to put your Darcs code? Try us.<br />
<br />
Patch-Tag is built with [http://happstack.com happstack], the continuation of the project formerly known as HAppS.<br />
</blockquote><br />
<br />
* [http://www.peerium.com Peerium, Inc] Cambridge, Massachusetts<br />
<blockquote><br />
At Peerium, we're striving to bring a new level of quality and efficiency to online communication and collaboration within virtual communities, social networks, and business environments. We believe that a new environment that supports the effortless sharing of both information and software will enable a level of online cooperation far beyond current Web-based technologies -- modern programming techniques will enable the creation of more robust and more powerful programs within these environments. To this end, we're building a new software platform for direct, real-time communication and collaboration within graphically rich environments. Peerium is located in the heart of Harvard Square in Cambridge, Massachusetts.<br />
</blockquote><br />
<br />
* [http://www.planit9.com/ PlanIt9]<br />
<br />
<blockquote><br />
PlanIt9 is a Yesod-based web application for defining, planning, scheduling and tracking tasks. It's designed to be fast, simple, collaborative and cost effective. We're currently signing up users for our beta program.<br />
</blockquote><br />
<br />
* [http://www.qualcomm.com/ Qualcomm, Inc]<br />
<br />
<blockquote><br />
Qualcomm uses Haskell to generate Lua bindings to the BREW platform <br />
</blockquote><br />
<br />
* [http://blog.sqreamtech.com/2013/09/using-haskell-at-sqream-technologies/ SQream]<br />
<br />
<blockquote><br />
At SQream, we use Haskell for a large part of our code. We use Haskell for the compiler, which takes SQL statements and turns them into low level instructions for the high performance CUDA runtime. We also use Haskell for rapid prototyping and for many auxiliary utilities.<br />
</blockquote><br />
<br />
* [http://cufp.org/conference/sessions/2013/jeff-epstein-parallel-scientific-building-scalable Parallel Scientific], Boulder, Colorado.<br />
<br />
<blockquote><br />
We are using Haskell to develop an ultra-scalable high-availability resource management system for big clusters (millions of nodes). A key element of the design is to provide scalable and reliable mechanisms for communicating failures and coordinating recovery transitions. <br />
</blockquote><br />
<br />
:: See Parallel Scientific's [http://cufp.org/conference/sessions/2013/jeff-epstein-parallel-scientific-building-scalable CUFP talk]<br />
<br />
* [http://www.renci.org/ Renaissaince Computing Institute], Chapel Hill, North Carolina<br />
<blockquote><br />
The Renaissance Computing Institute (RENCI), a multi-institutional organization, brings together multidisciplinary experts and advanced technological capabilities to address pressing research issues and to find solutions to complex problems that affect the quality of life in North Carolina, our nation and the world.<br />
<br />
Research scientists at RENCI have used Haskell for a number of projects, including [http://vis.renci.org/jeff/2009/08/26/open-sourcing-the-big-board/ The Big Board].<br />
</blockquote><br />
<br />
::RENCI's [http://cufp.galois.com/2009/abstracts.html#JeffersonHeard CUFP talk].<br />
<br />
* [http://samplecount.com Samplecount]<br />
<br />
<blockquote><br />
Samplecount develops mobile, location-aware sound and music applications. They are currently using Haskell for prototyping their server-side soundscape streaming components and as a cross-platform build tool for their mobile applications and frameworks.<br />
</blockquote><br />
<br />
* [http://sankelsoftware.com Sankel Software] Albuquerque, New Mexico<br />
<br />
<blockquote><br />
Sankel Software has been using Haskell since 2002 for both prototyping and deployment for technologies ranging from CAD/CAM to gaming and computer animation. We specialize in the development of user-friendly, large, long-term applications that solve difficult and conceptually intricate problems.<br />
</blockquote><br />
<br />
* [https://scrive.com/gb/en Scrive] <br />
<br />
<blockquote><br />
Scrive is a service for e-signing tenders, contracts, and other documents. We help our clients close deals faster, decrease their administrative burden, and improve their customers’ experience.<br />
</blockquote><br />
<br />
* [https://www.cee.siemens.com/web/at/en/csb/cvc/Pages/home.aspx Siemens Convergence Creators GmbH Austria]<br />
<br />
<blockquote><br />
Siemens CVC uses Haskell since a few years in the space domain. Starting with small tools like data conversion and automation of scripting tasks over installers we use Haskell currently for Space Protocol Proxies to allow connect different space systems (e.g. Cortex to NCTRS or SLE to NCTRS with COP-1 handling). The main use is currently a Simulator implemented in Haskell which handles parts of NCTRS (or SSB), the ground station and parts of the satellite to be able to make closed-loop tests for the SCOS-2000 based Mission Control System. It is in use for testing and debugging of the Mission Control System and for checking implementation of new features. It has served for various, currently active missions and also is in use for some missions to come.<br />
</blockquote><br />
<br />
* [http://www.signalicorp.com/index.htm Signali] Portland, Oregon<br />
<br />
<blockquote><br />
Signali Corp is a new custom hardware design company. Our chief products<br />
are custom IP cores targeted for embedded DSP and cryptographic<br />
applications. Our specialty is the design and implementation of<br />
computationally intensive, complex algorithms. The interfaces to each<br />
core are modular and can be very efficiently modified for your specific<br />
application. System-level integration and validation is crucial and is<br />
the majority of investment in a product.<br />
</blockquote><br />
<br />
* [http://www.soostone.com Soostone] New York, NY<br />
<br />
<blockquote><br />
Soostone is an advanced analytics technology provider specializing in algorithmic optimization opportunities in marketing, pricing, advertising, sales and product management. As the preferred language, Haskell is used intensively at Soostone in numerous applications including customized machine learning algorithms, models/simulations, real-time decision-making engines, DSL/EDSLs, web applications and high volume APIs.<br />
</blockquote><br />
<br />
* [http://www.standardchartered.com/home/en/index.html Standard Chartered]<br />
<br />
<blockquote><br />
Standard Chartered has a large group using Haskell for all aspects of its wholesale banking business.<br />
</blockquote><br />
<br />
* [http://www.starling-software.com/en/index.html Starling Software] Tokyo, Japan<br />
<blockquote><br />
Starling Software are developing a commercial automated options trading system <br />
in Haskell, and are migrating other parts of their software suite to<br />
Haskell.<br />
</blockquote><br />
<br />
::Starling Software's [http://www.starling-software.com/misc/icfp-2009-cjs.pdf experience building real time trading systems in Haskell] <br />
<br />
<br />
* [http://www.sensor-sense.nl Sensor Sense] Nijmegen, The Netherlands<br />
<br />
<blockquote><br />
Sensor Sense is offering high technology systems for gas measurements in the ''ppbv'' down to ''pptv'' range. We use Haskell for the embedded control software of our trace gas detectors.<br />
</blockquote><br />
<br />
:: For more information see Senor Sense's [http://www.reddit.com/r/haskell/comments/1clkjb/job_opening_for_haskell_developer_in_nijmegen_nl/ position advertisement]<br />
<br />
* [http://www.silk.co Silk] Amsterdam, The Netherlands<br />
<br />
<blockquote><br />
Silk investigates and develops new ways of creating and consuming online content. Their [http://www.silk.co/ Silk] application makes it easy to filter and visualize large amounts of information.<br />
</blockquote><br />
<br />
:: Silk's blog on [http://engineering.silk.co/post/31920990633/why-we-use-haskell/ why they use Haskell]<br />
:: A [http://thenextweb.com/eu/2011/04/28/filter-and-visualize-data-in-seconds-with-silk/ review of Silk]<br />
<br />
* [http://skedge.me/ Skedge Me]<br />
<blockquote><br />
skedge.me is an online scheduling platform that allows businesses to completely automate the process of making appointments, such as customer visits, job interviews, and tutoring sessions.<br />
</blockquote><br />
<br />
:: See more in their [http://cufp.org/conference/sessions/2013/ryan-trinkle-skedgeme-enterprise-appointment-sched CUFP talk]<br />
:: See their 2014 [http://functionaljobs.com/jobs/8712-haskell-developer-at-skedgeme job advertisement]<br />
<br />
* [http://www.suite-sol.com/ Suite Solutions]<br />
<blockquote><br />
Suite Solutions provides products and solutions in support of large sets of technical documentation based on [http://en.wikipedia.org/wiki/Darwin_Information_Typing_Architecture DITA] for general technical documentation, and other more specialized XML and SGML formats for specific industries such as the aerospace industry. Many of Suite Solutions' products and solutions, such as the featured products [http://www.suite-sol.com/pages/solutions/suitehelp.html SuiteHelp] and [http://www.suite-sol.com/pages/solutions/suite-social-kb.html SuiteShare], are written in Haskell.<br />
</blockquote><br />
<br />
* [http://www.tabula.com/ Tabula.com]<br />
<blockquote><br />
Tabula is a privately held fabless semiconductor company developing 3-D Programmable Logic Devices. Haskell is used for internal compiler toolchains related to hardware design.<br />
</blockquote><br />
<br />
* [http://tsurucapital.com Tsuru Capital] Tokyo, Japan<br />
<blockquote><br />
Tsuru Capital is operating an automated options trading system written in Haskell.<br />
</blockquote><br />
<br />
::[http://haskell.org/communities/05-2010/html/report.html#sect7.6 Tsuru Capital's HCAR submission]<br />
<br />
* [http://tupil.com/ Tupil] Utrecht, The Netherlands<br />
<br />
<blockquote><br />
Tupil is a Dutch company that built software for clients, written in Haskell. Tupil used Haskell for the speed in development and resulting software quality. The company is founded by Chris Eidhof and Eelco Lempsink. Currently they build iPhone/iPad applications in Objective-C.<br />
</blockquote><br />
<br />
:: Tupil's experience building [http://blog.tupil.com/building-commercial-haskell-applications/ commercial web apps in Haskell]<br />
<br />
<br />
If you're using Haskell commercially, please add your details here.<br />
<br />
== The Industrial Haskell Group ==<br />
<br />
The [http://industry.haskell.org/ Industrial Haskell Group (IHG)] is an organisation to support the needs of commercial users of the Haskell programming language. <br />
<br />
== Jobs and recruitment ==<br />
<br />
[[Jobs|Haskell jobs]] on the HaskellWiki.<br />
<br />
[http://www.haskellers.com/jobs Jobs at Haskellers.com].<br />
<br />
== Consultants ==<br />
<br />
[[Consultants]]<br />
<br />
== Commercial Users of Functional Programming Workshop ==<br />
<br />
[http://www.galois.com/cufp/ Commercial Users of Functional Programming]<br />
<br />
The goal of [http://www.galois.com/cufp/ CUFP] is to build a community<br />
for users of functional programming languages and technology, be they<br />
using functional languages in their professional lives, in an open<br />
source project (other than implementation of functional languages), as a<br />
hobby, or any combination thereof. In short: anyone who uses functional<br />
programming as a means, but not an end.<br />
<br />
[[Category:Community]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=HacBerlin2014&diff=58942HacBerlin20142014-09-29T06:12:17Z<p>Dreixel: /* Talks */</p>
<hr />
<div>----<br />
{|<br />
|When:<br />
|Friday 26 September 2014 - Sunday 28 September 2014<br />
|-<br />
|Hours:<br />
|Fri 14:00 - 19:00, Sat 09:00 - 18:00, Sun 09:00 - 15:00<br />
|-<br />
|Where:<br />
|Alt-Reinickendorf 25, Berlin, Germany (office of [http://checkpad.de Lohmann & Birkner GmbH], [https://mapsengine.google.com/map/edit?mid=z2Lvu68pMn-o.kak1M7mHoWKk Map])<br />
|-<br />
|Cost:<br />
| free<br />
|}<br />
----<br />
<br />
[[File:HacBerlin_Logo.png]]<br />
<br />
== News ==<br />
<br />
* There is a list of [[/Topics|topics]] people plan to work on. Please extend, update and refine this list.<br />
* There is a [[/Participants|list of participants]]. We will update this list occasionally.<br />
* ''[http://goo.gl/aLfnWu Please register!]''<br />
* [http://www.andres-loeh.de/ Andres Löh] will give a talk with the title ''Beyond Parsec -- Revisiting Parser Combinators''. Thanks Andres!<br />
* [http://dreixel.net/ José Pedro Magalhães] will talk about ''Chordify: Advanced Functional Programming for Fun and Profit''. Thanks Pedro!'<br />
<br />
== About ==<br />
<br />
HacBerlin is another Haskell Hackathon, where Haskell programmers from all around the world meet in Berlin, discuss, hack together and improve the Haskell infrastructure. We welcome all programmers interested in Haskell, beginners and experts!<br />
<br />
== Schedule ==<br />
<br />
=== Fri 26 Sep 2014 (14:00 - open end) ===<br />
<br />
Hacking hours: 14:00 - 19:00<br />
<br />
==== Project introduction (15:00) ====<br />
<br />
Please come to the project introduction at 15:00 to see what people will do during the hackathon. If you have a great project that you want to share with your fellow Haskellers, please be prepared to give a ''short'' introduction.<br />
<br />
==== Barbecue (19:00) ====<br />
<br />
We'll have a barbecue just outside the venue starting approx at 19:00.<br />
<br />
=== Sat 27 Sep 2014 (09:00 - 18:00) ===<br />
<br />
Hacking hours: 09:00 - 18:00<br />
<br />
==== Talks (14:00) ====<br />
<br />
===== Beyond Parsec -- Revisiting Parser Combinators =====<br />
<br />
[http://www.andres-loeh.de/ Andres Löh]<br />
<br />
''Abstract''<br />
<br />
It is folklore that Haskell is excellent for EDSLs, and that parsers<br />
are a prime example of how easy and compelling it is to embed a<br />
domain-specific language into Haskell itself rather than to use a<br />
separate tool. However, the most widely used parser combinator<br />
library, Parsec, is quite old by now. We'll look at a number of other,<br />
somewhat more recent libraries and discuss how they are different and<br />
perhaps better. We will also see a good example of the difference in<br />
expressive power between monads and applicative functors, and the<br />
tradeoffs associated with that.<br />
<br />
<br />
===== Chordify: Advanced Functional Programming for Fun and Profit =====<br />
<br />
[http://dreixel.net/ José Pedro Magalhães] <br />
<br />
''Abstract''<br />
<br />
Functional programming, especially when using advanced techniques such as GADTs, type functions, and kind polymorphism, is not only fun; it can also be profitable! In this talk I'll describe my experience in using advanced functional programming in Haskell within Chordify, a web startup that brings chord recognition to the masses.<br />
<br />
[http://dreixel.net/research/pdf/cafpfp_pres_HacBerlin14.pdf Slides (PDF)].<br />
<br />
=== Sun 28 Sep 2014 (09:00 - 15:00) ===<br />
<br />
Hacking hours: 09:00 - 15:00<br />
<br />
==== Demo-Session, lightning talks, discussion (11:00) ====<br />
<br />
Everyone is invited to give a short demo or talk (5 minutes) at the session at 11:00. <br />
<br />
===== Talks =====<br />
<br />
* LambdaCube 3D (https://prezi.com/4vqrv8l3wfq9/lambdacube-3d-short-intro/)<br />
* ghc-imported-from<br />
* Deriving clause for arbitrary classes (http://dreixel.net/research/pdf/dcac_pres_HacBerlin14.pdf)<br />
* Type-safe routing for Spock (http://slides.com/timjb/typed-routes-in-spock)<br />
* Generator for commandline parsing and completion<br />
<br />
== Registration ==<br />
<br />
We only have restricted capacities, so please [http://goo.gl/aLfnWu register] early.<br />
<br />
== Sponsors ==<br />
<br />
The Haskell hackathon is sponsored by [http://www.lohmann-birkner.de/ Lohmann & Birkner Health Care Consulting GmbH].<br />
[[File:Lohmann_Birkner.png]]<br />
<br />
== Location ==<br />
<br />
The Hackathon takes place at the office rooms of [http://checkpad.de Lohmann & Birkner GmbH] ([https://mapsengine.google.com/map/edit?mid=z2Lvu68pMn-o.kak1M7mHoWKk Map])<br />
<br />
''Address:''<br />
<br />
Lohmann & Birkner<br><br />
Health Care Consulting GmbH<br><br />
Alt-Reinickendorf 25<br><br />
D-13407 Berlin<br />
<br />
=== Getting to the venue ===<br />
<br />
You can reach the venue of the hackathon by train, car, or plane.<br />
<br />
==== Train ====<br />
<br />
* U-Bahn: U8, exit at Paracelsus-Bad<br />
* S-Bahn: S25, exit Alt-Reinickendorf <br />
<br />
From these two stations, it is a [http://www.lohmann-birkner.de/de-wAssets/docs/LuB_Anfahrt.pdf 5 minutes walk] to the venue.<br />
<br />
''From Berlin main station:''<br />
<br />
* Take the S-Bahn: either S5 (direction Strausberg) or S7 (direction Ahrensfelde) or the S75 (direction Wartenberg) to Alexanderplatz<br />
* Then take the U-Bahn U8 (direction Wittenau), exit at Paracelsus-Bad<br />
<br />
==== Car ====<br />
<br />
Autobahn A 111, exit "Holzhauser Straße". Then follow your navigation system.<br />
<br />
==== Plane ====<br />
<br />
* Tegel airport: approx. 20 minutes by taxi, approx. 30 minutes by bus. For the bus, you first take the bus 128 from "Luftfracht Berlin" to Kurt-Schumacher-Platz (direction "Osloer Straße"). At Kurt-Schumacher-Platz, you take bus 122 to Paracelsus-Bad (direction Waidmannslust).<br />
* Schönefeld airport: approx. 45 minutes by taxi, approx. 60 minutes by train. For the latter option, you take a train (RB or RE) from "Berlin-Schönefeld Flughafen" to Alexanderplatz (direction Nauen). There, you take the U-Bahn U8 (direction Wittenau) and exit at Paracelsus-Bad.<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.hotel-berlin-city.de/ ibis Hotel Berlin Airport Tegel]. The venue is in walking distance (~ 500 meter).<br />
* [http://www.circus-berlin.de/hostel/ Circus Hostel]. To get to the venue, you simply take the U8 at "Rosenthaler Platz" (direction Wittenau) and exit at Paracelsus-Bad (~ 15 min).<br />
* [http://www.alcatraz-backpacker.de/de/kontakt/kontakt.html Backpacker Alcatraz]. To get to the venue, you first take the M10 at "Eberswalder Str" (direction Nordbahnhof). At "Bernauer Str" , you switch to the U8 (direction Wittenau) and exit at Paracelsus-Bad (~ 30 min).<br />
* [http://www.cityhostel-berlin.com/ City Hostel]. To get to the venue, you first take the U6 at Stadtmitte to "Kurt-Schumacher-Platz". There, you switch to the bus 122 (direction "Waidmannslust, Titiseestr.") and exit at Paracelsus-Bad (~ 30 min).<br />
<br />
== Equipment ==<br />
<br />
Please bring your own laptop. We will provide multiplugs, but make sure that you have either a [http://en.wikipedia.org/wiki/Schuko Schukoplug] or a [http://en.wikipedia.org/wiki/Europlug Europlug].<br />
<br />
== Organizers ==<br />
<br />
You can reach the organizers by writing an [mailto:hacberlin2014@cp-med.com email].<br />
<br />
* [http://stefanwehr.de Stefan Wehr]<br />
* David Leuschner</div>Dreixelhttps://wiki.haskell.org/index.php?title=HacBerlin2014&diff=58917HacBerlin20142014-09-28T09:43:14Z<p>Dreixel: /* Chordify: Advanced Functional Programming for Fun and Profit */</p>
<hr />
<div>----<br />
{|<br />
|When:<br />
|Friday 26 September 2014 - Sunday 28 September 2014<br />
|-<br />
|Hours:<br />
|Fri 14:00 - 19:00, Sat 09:00 - 18:00, Sun 09:00 - 15:00<br />
|-<br />
|Where:<br />
|Alt-Reinickendorf 25, Berlin, Germany (office of [http://checkpad.de Lohmann & Birkner GmbH], [https://mapsengine.google.com/map/edit?mid=z2Lvu68pMn-o.kak1M7mHoWKk Map])<br />
|-<br />
|Cost:<br />
| free<br />
|}<br />
----<br />
<br />
[[File:HacBerlin_Logo.png]]<br />
<br />
== News ==<br />
<br />
* There is a list of [[/Topics|topics]] people plan to work on. Please extend, update and refine this list.<br />
* There is a [[/Participants|list of participants]]. We will update this list occasionally.<br />
* ''[http://goo.gl/aLfnWu Please register!]''<br />
* [http://www.andres-loeh.de/ Andres Löh] will give a talk with the title ''Beyond Parsec -- Revisiting Parser Combinators''. Thanks Andres!<br />
* [http://dreixel.net/ José Pedro Magalhães] will talk about ''Chordify: Advanced Functional Programming for Fun and Profit''. Thanks Pedro!'<br />
<br />
== About ==<br />
<br />
HacBerlin is another Haskell Hackathon, where Haskell programmers from all around the world meet in Berlin, discuss, hack together and improve the Haskell infrastructure. We welcome all programmers interested in Haskell, beginners and experts!<br />
<br />
== Schedule ==<br />
<br />
=== Fri 26 Sep 2014 (14:00 - open end) ===<br />
<br />
Hacking hours: 14:00 - 19:00<br />
<br />
==== Project introduction (15:00) ====<br />
<br />
Please come to the project introduction at 15:00 to see what people will do during the hackathon. If you have a great project that you want to share with your fellow Haskellers, please be prepared to give a ''short'' introduction.<br />
<br />
==== Barbecue (19:00) ====<br />
<br />
We'll have a barbecue just outside the venue starting approx at 19:00.<br />
<br />
=== Sat 27 Sep 2014 (09:00 - 18:00) ===<br />
<br />
Hacking hours: 09:00 - 18:00<br />
<br />
==== Talks (14:00) ====<br />
<br />
===== Beyond Parsec -- Revisiting Parser Combinators =====<br />
<br />
[http://www.andres-loeh.de/ Andres Löh]<br />
<br />
''Abstract''<br />
<br />
It is folklore that Haskell is excellent for EDSLs, and that parsers<br />
are a prime example of how easy and compelling it is to embed a<br />
domain-specific language into Haskell itself rather than to use a<br />
separate tool. However, the most widely used parser combinator<br />
library, Parsec, is quite old by now. We'll look at a number of other,<br />
somewhat more recent libraries and discuss how they are different and<br />
perhaps better. We will also see a good example of the difference in<br />
expressive power between monads and applicative functors, and the<br />
tradeoffs associated with that.<br />
<br />
<br />
===== Chordify: Advanced Functional Programming for Fun and Profit =====<br />
<br />
[http://dreixel.net/ José Pedro Magalhães] <br />
<br />
''Abstract''<br />
<br />
Functional programming, especially when using advanced techniques such as GADTs, type functions, and kind polymorphism, is not only fun; it can also be profitable! In this talk I'll describe my experience in using advanced functional programming in Haskell within Chordify, a web startup that brings chord recognition to the masses.<br />
<br />
[http://dreixel.net/research/pdf/cafpfp_pres_HacBerlin14.pdf Slides (PDF)].<br />
<br />
=== Sun 28 Sep 2014 (09:00 - 15:00) ===<br />
<br />
Hacking hours: 09:00 - 15:00<br />
<br />
==== Demo-Session, lightning talks, discussion (11:00) ====<br />
<br />
Everyone is invited to give a short demo or talk (5 minutes) at the session at 11:00. We will announce details during the hackathon.<br />
<br />
== Registration ==<br />
<br />
We only have restricted capacities, so please [http://goo.gl/aLfnWu register] early.<br />
<br />
== Sponsors ==<br />
<br />
The Haskell hackathon is sponsored by [http://www.lohmann-birkner.de/ Lohmann & Birkner Health Care Consulting GmbH].<br />
[[File:Lohmann_Birkner.png]]<br />
<br />
== Location ==<br />
<br />
The Hackathon takes place at the office rooms of [http://checkpad.de Lohmann & Birkner GmbH] ([https://mapsengine.google.com/map/edit?mid=z2Lvu68pMn-o.kak1M7mHoWKk Map])<br />
<br />
''Address:''<br />
<br />
Lohmann & Birkner<br><br />
Health Care Consulting GmbH<br><br />
Alt-Reinickendorf 25<br><br />
D-13407 Berlin<br />
<br />
=== Getting to the venue ===<br />
<br />
You can reach the venue of the hackathon by train, car, or plane.<br />
<br />
==== Train ====<br />
<br />
* U-Bahn: U8, exit at Paracelsus-Bad<br />
* S-Bahn: S25, exit Alt-Reinickendorf <br />
<br />
From these two stations, it is a [http://www.lohmann-birkner.de/de-wAssets/docs/LuB_Anfahrt.pdf 5 minutes walk] to the venue.<br />
<br />
''From Berlin main station:''<br />
<br />
* Take the S-Bahn: either S5 (direction Strausberg) or S7 (direction Ahrensfelde) or the S75 (direction Wartenberg) to Alexanderplatz<br />
* Then take the U-Bahn U8 (direction Wittenau), exit at Paracelsus-Bad<br />
<br />
==== Car ====<br />
<br />
Autobahn A 111, exit "Holzhauser Straße". Then follow your navigation system.<br />
<br />
==== Plane ====<br />
<br />
* Tegel airport: approx. 20 minutes by taxi, approx. 30 minutes by bus. For the bus, you first take the bus 128 from "Luftfracht Berlin" to Kurt-Schumacher-Platz (direction "Osloer Straße"). At Kurt-Schumacher-Platz, you take bus 122 to Paracelsus-Bad (direction Waidmannslust).<br />
* Schönefeld airport: approx. 45 minutes by taxi, approx. 60 minutes by train. For the latter option, you take a train (RB or RE) from "Berlin-Schönefeld Flughafen" to Alexanderplatz (direction Nauen). There, you take the U-Bahn U8 (direction Wittenau) and exit at Paracelsus-Bad.<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.hotel-berlin-city.de/ ibis Hotel Berlin Airport Tegel]. The venue is in walking distance (~ 500 meter).<br />
* [http://www.circus-berlin.de/hostel/ Circus Hostel]. To get to the venue, you simply take the U8 at "Rosenthaler Platz" (direction Wittenau) and exit at Paracelsus-Bad (~ 15 min).<br />
* [http://www.alcatraz-backpacker.de/de/kontakt/kontakt.html Backpacker Alcatraz]. To get to the venue, you first take the M10 at "Eberswalder Str" (direction Nordbahnhof). At "Bernauer Str" , you switch to the U8 (direction Wittenau) and exit at Paracelsus-Bad (~ 30 min).<br />
* [http://www.cityhostel-berlin.com/ City Hostel]. To get to the venue, you first take the U6 at Stadtmitte to "Kurt-Schumacher-Platz". There, you switch to the bus 122 (direction "Waidmannslust, Titiseestr.") and exit at Paracelsus-Bad (~ 30 min).<br />
<br />
== Equipment ==<br />
<br />
Please bring your own laptop. We will provide multiplugs, but make sure that you have either a [http://en.wikipedia.org/wiki/Schuko Schukoplug] or a [http://en.wikipedia.org/wiki/Europlug Europlug].<br />
<br />
== Organizers ==<br />
<br />
You can reach the organizers by writing an [mailto:hacberlin2014@cp-med.com email].<br />
<br />
* [http://stefanwehr.de Stefan Wehr]<br />
* David Leuschner</div>Dreixelhttps://wiki.haskell.org/index.php?title=HacBerlin2014/Topics&diff=58896HacBerlin2014/Topics2014-09-26T12:14:51Z<p>Dreixel: </p>
<hr />
<div>Here is a list of potential topics for [[HacBerlin2014|HacBerlin2014]], originally extracted from the notes participants gave when registering.<br />
<br />
Please extend, update and refine this list!<br />
<br />
* Darcs, darcsden<br />
* cabal2nix<br />
* A GHC bug squashing race would be fun.<br />
* Perhaps also some GHC hacking.<br />
* ghc, extensible-effects, (progression), (complexity)<br />
* ghc-imported-from<br />
* I'd like to get to know the GHC codebase / become involved in compiler/RTS development<br />
* I'm interested in doing some work on pattern synonyms in GHC.<br />
* Not sure yet, I have some ideas for work on Cabal or Hackage.<br />
* cabal-install. Make the constraint solver more efficient. <br />
* Library maintenance. I'm going to try to make maintenance releases for a number of libraries and tools, including generics-sop, multirec, gdiff, tilt, lhs2tex<br />
* Some SaaS webapp, or some systems tool<br />
* most likely Haskell + FPGAs, but for it might be easier<br />
* A lazy evaluation Database called Gödel"<br />
* Omega 2 (theory and footwork)<br />
* I'm also interested in game / openGL programming<br />
* I've got some web development (backend / app server) projects of my on; sharing experience with other Haskellers about that would be nice.<br />
* Frankly, I haven't gotten my hands dirty on any larger projects yet. Nevertheless, I'd be glad to jump in anywhere a beginner isn't too much of a hassle!"<br />
* Frozone<br />
* dockercook<br />
* rocksdb-haskell, rocksdb haskell server<br />
* I am building a gossip message bus in Erlang + Thrift and would like to build a client in Haskell. No prior experience with Haskell so should be rather interesting.<br />
* I would like to implement a decision tree library in Haskell.<br />
* Not decided, yet. Was also thinking that universal Cabal file parsing library would be helpful. Most importantly something that preserves original formatting. Just a thought. :-)<br />
* TracWiki writer for Pandoc (or if some other project catches my eye...)<br />
* LambdaCube 3D Stunts (game remake with lambdacube) LambdaCube Stunts Resurrection<br />
* One of https://github.com/ocharles/engine.io https://github.com/meiersi/blaze-react https://github.com/ghcjs/ghcjs-vdom<br />
* Having not that much experience in Haskell, i'm interested in almost everything, that is within my comfort zone. An idea i have for some time now is to make Hackage a little friendlier by giving users the possibility to sort/filter search results by certain criteria. Like filtering out packages, that were lastly updated a couple of years ago or sort them by 'newest upload' first.<br />
* data synchronization (as in http://ipsit.bu.edu/documents/ieee-it3-web.pdf)<br />
* improved build system for Haskell (hermetic builds (e.g. http://blog.johantibell.com/2012/03/cabal-of-my-dreams.html)"<br />
* LensRef<br />
* LGtk<br />
* I am a beginner in haskell, have worked through the most chapters of the wikipedia-book on haskell. Monads I find not especially interesting, but complicated. Types are interesting. So I'm open for much.<br />
* whatever you let me work on ;)<br />
* Whatever project I'll be able to help with.<br />
* something neat. I'm very much a newbie, so I'll just see how I can help.<br />
* Infrastructure, Web, E-Commerce<br />
* I don't have a strong preference about that. i never visited a hackathon before so i think i have to see how everything works when i am at the hackathon.<br />
* also things related to DICOM file archiving.<br />
* Ontology Editor, 3d Tree Canvas,...<br />
* postgresql-crud (to be announced), monad-classes, wai-predicates, anything interesting.<br />
* Getting rid of cabal hell. Doing DevOps stuff and compiling a working tool chain. Continue "LYAH"<br />
* Parsing tools. <br />
* language-swift: Starting as new project. Library to analyse and generate code for Apple's new programming language Swift. Similar to language-c and hopefully at some point the base for something hlint like for Swift. <br />
<br />
== Project Proposal for the haskell Hackathon Berlin 2015 ==<br />
<br />
A Testcase generator for system tests.<br />
With as few lines as possible generate as most test scripts as possible, part test-cases are combinable.<br />
Language for generating the testcases: haskell, with embedded DSL.<br />
Language of the test scripts: ruby, python, perl, c++, ... (it depends)<br />
test target: an embedded device, a mail server, a web-service, ..., but at first no GUI.<br />
<br />
The existing example:<br />
There exists a test generating tool named ""tedeso"" by Siemens.<br />
Tedeso has 2 major building blocks: <br />
- variables/instances of classes with attributes: The attributes can have different values and the test script is executed with all instances. Each test script uses one instance.<br />
- branching: do this or do this or do this: the different test scripts are generated by following the different pathes. Each test script is one path.<br />
- a GUI, with which you can draw a testcase. But this can be omitted. In my point of view, it is not practical. A test script written in a good embedded dsl is better readable and better comparable with older versions.<br />
<br />
The haskell testcase generator shall go beyond Tedeso:<br />
It shall easily be possible to combine (parts of) testcases to build bigger ones. Haskell is good for that purpose, because the part test scripts are functions, without side effects.<br />
The testcases could have attributes, which say something of the condition or state that is fulfilled or reached by the (part-)test script.<br />
<br />
Bigger challenges:<br />
<br />
1.) If the attributes of the part test scripts ar cleverly chosen, can they form a kind of formal specification of the system under test?<br />
<br />
2.)If someone asks, possibly after years, what the system under test does under certain circumstances, can you ask the set of your test programs what happens ? Possibly: "" Yes, we have tested it in 2015, and the test ran ok!"", without actually running the test, just by typing the specification of the question to your test environment ?<br />
A solution could be a database of test cases or a analyzation of the test programs (perhaps with template haskell? I do not know much about it.)<br />
<br />
3.)Can one make a test case by saying: ""<br />
a.) Go to state X, in any possible way. <br />
b.) Do this special. (perhaps test a new requirement, that is just implemented)<br />
c.) After that you are in state Y. Do some arbitrarily chosen part-testcases begining with that state Y."" <br />
<br />
The 2 major building blocks of tedeso, variables and branching, are easily done with haskell. That have I already programmed, as a beginner in haskell, who i am. But there seems to be much possible in testing with haskell. <br />
For Open source programs there is the need for good system test tools. When I look at open source source code, I do not find many test cases, if any. Perhaps could a easy usable system test environment improve the quality of open source software.<br />
<br />
== Pedro's working topics ==<br />
<br />
I plan to be mostly working on Chordify-related stuff. But I will also discuss some GHC Generics stuff with Gabor and Andres, and I might have a look at some of the tickets on this list: https://ghc.haskell.org/trac/ghc/wiki/PedrosTickets<br />
<br />
In general, if you're interested in some GHC hacking, I can try to help you get along the source code.<br />
<br />
Also, I think it would be great to have Haskell implementations of the constant-Q transform and the reassignment spectrogram that are independent of the FFT implementation, and use REPA or Vector under the hood. If you happen to be interested in this, do get in touch.</div>Dreixelhttps://wiki.haskell.org/index.php?title=HacBerlin2014/Topics&diff=58890HacBerlin2014/Topics2014-09-24T14:58:01Z<p>Dreixel: </p>
<hr />
<div>Here is a list of potential topics for [[HacBerlin2014|HacBerlin2014]], originally extracted from the notes participants gave when registering.<br />
<br />
Please extend, update and refine this list!<br />
<br />
* Darcs, darcsden<br />
* cabal2nix<br />
* A GHC bug squashing race would be fun.<br />
* Perhaps also some GHC hacking.<br />
* ghc, extensible-effects, (progression), (complexity)<br />
* ghc-imported-from<br />
* I'd like to get to know the GHC codebase / become involved in compiler/RTS development<br />
* I'm interested in doing some work on pattern synonyms in GHC.<br />
* Not sure yet, I have some ideas for work on Cabal or Hackage.<br />
* cabal-install. Make the constraint solver more efficient. <br />
* Library maintenance. I'm going to try to make maintenance releases for a number of libraries and tools, including generics-sop, multirec, gdiff, tilt, lhs2tex<br />
* Some SaaS webapp, or some systems tool<br />
* most likely Haskell + FPGAs, but for it might be easier<br />
* A lazy evaluation Database called Gödel"<br />
* Omega 2 (theory and footwork)<br />
* I'm also interested in game / openGL programming<br />
* I've got some web development (backend / app server) projects of my on; sharing experience with other Haskellers about that would be nice.<br />
* Frankly, I haven't gotten my hands dirty on any larger projects yet. Nevertheless, I'd be glad to jump in anywhere a beginner isn't too much of a hassle!"<br />
* Frozone<br />
* dockercook<br />
* rocksdb-haskell, rocksdb haskell server<br />
* I am building a gossip message bus in Erlang + Thrift and would like to build a client in Haskell. No prior experience with Haskell so should be rather interesting.<br />
* I would like to implement a decision tree library in Haskell.<br />
* Not decided, yet. Was also thinking that universal Cabal file parsing library would be helpful. Most importantly something that preserves original formatting. Just a thought. :-)<br />
* TracWiki writer for Pandoc (or if some other project catches my eye...)<br />
* LambdaCube 3D Stunts (game remake with lambdacube) LambdaCube Stunts Resurrection<br />
* One of https://github.com/ocharles/engine.io https://github.com/meiersi/blaze-react https://github.com/ghcjs/ghcjs-vdom<br />
* Having not that much experience in Haskell, i'm interested in almost everything, that is within my comfort zone. An idea i have for some time now is to make Hackage a little friendlier by giving users the possibility to sort/filter search results by certain criteria. Like filtering out packages, that were lastly updated a couple of years ago or sort them by 'newest upload' first.<br />
* data synchronization (as in http://ipsit.bu.edu/documents/ieee-it3-web.pdf)<br />
* improved build system for Haskell (hermetic builds (e.g. http://blog.johantibell.com/2012/03/cabal-of-my-dreams.html)"<br />
* LensRef<br />
* LGtk<br />
* I am a beginner in haskell, have worked through the most chapters of the wikipedia-book on haskell. Monads I find not especially interesting, but complicated. Types are interesting. So I'm open for much.<br />
* whatever you let me work on ;)<br />
* Whatever project I'll be able to help with.<br />
* something neat. I'm very much a newbie, so I'll just see how I can help.<br />
* Infrastructure, Web, E-Commerce<br />
* I don't have a strong preference about that. i never visited a hackathon before so i think i have to see how everything works when i am at the hackathon.<br />
* also things related to DICOM file archiving.<br />
* Ontology Editor, 3d Tree Canvas,...<br />
* postgresql-crud (to be announced), monad-classes, wai-predicates, anything interesting.<br />
* Getting rid of cabal hell. Doing DevOps stuff and compiling a working tool chain. Continue "LYAH"<br />
* Parsing tools. <br />
* language-swift: Starting as new project. Library to analyse and generate code for Apple's new programming language Swift. Similar to language-c and hopefully at some point the base for something hlint like for Swift. <br />
<br />
== Project Proposal for the haskell Hackathon Berlin 2015 ==<br />
<br />
A Testcase generator for system tests.<br />
With as few lines as possible generate as most test scripts as possible, part test-cases are combinable.<br />
Language for generating the testcases: haskell, with embedded DSL.<br />
Language of the test scripts: ruby, python, perl, c++, ... (it depends)<br />
test target: an embedded device, a mail server, a web-service, ..., but at first no GUI.<br />
<br />
The existing example:<br />
There exists a test generating tool named ""tedeso"" by Siemens.<br />
Tedeso has 2 major building blocks: <br />
- variables/instances of classes with attributes: The attributes can have different values and the test script is executed with all instances. Each test script uses one instance.<br />
- branching: do this or do this or do this: the different test scripts are generated by following the different pathes. Each test script is one path.<br />
- a GUI, with which you can draw a testcase. But this can be omitted. In my point of view, it is not practical. A test script written in a good embedded dsl is better readable and better comparable with older versions.<br />
<br />
The haskell testcase generator shall go beyond Tedeso:<br />
It shall easily be possible to combine (parts of) testcases to build bigger ones. Haskell is good for that purpose, because the part test scripts are functions, without side effects.<br />
The testcases could have attributes, which say something of the condition or state that is fulfilled or reached by the (part-)test script.<br />
<br />
Bigger challenges:<br />
<br />
1.) If the attributes of the part test scripts ar cleverly chosen, can they form a kind of formal specification of the system under test?<br />
<br />
2.)If someone asks, possibly after years, what the system under test does under certain circumstances, can you ask the set of your test programs what happens ? Possibly: "" Yes, we have tested it in 2015, and the test ran ok!"", without actually running the test, just by typing the specification of the question to your test environment ?<br />
A solution could be a database of test cases or a analyzation of the test programs (perhaps with template haskell? I do not know much about it.)<br />
<br />
3.)Can one make a test case by saying: ""<br />
a.) Go to state X, in any possible way. <br />
b.) Do this special. (perhaps test a new requirement, that is just implemented)<br />
c.) After that you are in state Y. Do some arbitrarily chosen part-testcases begining with that state Y."" <br />
<br />
The 2 major building blocks of tedeso, variables and branching, are easily done with haskell. That have I already programmed, as a beginner in haskell, who i am. But there seems to be much possible in testing with haskell. <br />
For Open source programs there is the need for good system test tools. When I look at open source source code, I do not find many test cases, if any. Perhaps could a easy usable system test environment improve the quality of open source software.<br />
<br />
== Pedro's working topics ==<br />
<br />
I plan to be mostly working on Chordify-related stuff. But I will also discuss some GHC Generics stuff with Gabor and Andres, and I might have a look at some of the tickets on this list: https://ghc.haskell.org/trac/ghc/wiki/PedrosTickets<br />
<br />
In general, if you're interested in some GHC hacking, I can try to help you get along the source code.</div>Dreixelhttps://wiki.haskell.org/index.php?title=HacBerlin2014/Topics&diff=58889HacBerlin2014/Topics2014-09-24T14:57:08Z<p>Dreixel: </p>
<hr />
<div>Here is a list of potential topics for [[HacBerlin2014|HacBerlin2014]], originally extracted from the notes participants gave when registering.<br />
<br />
Please extend, update and refine this list!<br />
<br />
* Darcs, darcsden<br />
* cabal2nix<br />
* A GHC bug squashing race would be fun.<br />
* Perhaps also some GHC hacking.<br />
* ghc, extensible-effects, (progression), (complexity)<br />
* ghc-imported-from<br />
* I'd like to get to know the GHC codebase / become involved in compiler/RTS development<br />
* I'm interested in doing some work on pattern synonyms in GHC.<br />
* Not sure yet, I have some ideas for work on Cabal or Hackage.<br />
* cabal-install. Make the constraint solver more efficient. <br />
* Library maintenance. I'm going to try to make maintenance releases for a number of libraries and tools, including generics-sop, multirec, gdiff, tilt, lhs2tex<br />
* Some SaaS webapp, or some systems tool<br />
* most likely Haskell + FPGAs, but for it might be easier<br />
* A lazy evaluation Database called Gödel"<br />
* Omega 2 (theory and footwork)<br />
* I'm also interested in game / openGL programming<br />
* I've got some web development (backend / app server) projects of my on; sharing experience with other Haskellers about that would be nice.<br />
* Frankly, I haven't gotten my hands dirty on any larger projects yet. Nevertheless, I'd be glad to jump in anywhere a beginner isn't too much of a hassle!"<br />
* Frozone<br />
* dockercook<br />
* rocksdb-haskell, rocksdb haskell server<br />
* I am building a gossip message bus in Erlang + Thrift and would like to build a client in Haskell. No prior experience with Haskell so should be rather interesting.<br />
* I would like to implement a decision tree library in Haskell.<br />
* Not decided, yet. Was also thinking that universal Cabal file parsing library would be helpful. Most importantly something that preserves original formatting. Just a thought. :-)<br />
* TracWiki writer for Pandoc (or if some other project catches my eye...)<br />
* LambdaCube 3D Stunts (game remake with lambdacube) LambdaCube Stunts Resurrection<br />
* One of https://github.com/ocharles/engine.io https://github.com/meiersi/blaze-react https://github.com/ghcjs/ghcjs-vdom<br />
* Having not that much experience in Haskell, i'm interested in almost everything, that is within my comfort zone. An idea i have for some time now is to make Hackage a little friendlier by giving users the possibility to sort/filter search results by certain criteria. Like filtering out packages, that were lastly updated a couple of years ago or sort them by 'newest upload' first.<br />
* data synchronization (as in http://ipsit.bu.edu/documents/ieee-it3-web.pdf)<br />
* improved build system for Haskell (hermetic builds (e.g. http://blog.johantibell.com/2012/03/cabal-of-my-dreams.html)"<br />
* LensRef<br />
* LGtk<br />
* I am a beginner in haskell, have worked through the most chapters of the wikipedia-book on haskell. Monads I find not especially interesting, but complicated. Types are interesting. So I'm open for much.<br />
* whatever you let me work on ;)<br />
* Whatever project I'll be able to help with.<br />
* something neat. I'm very much a newbie, so I'll just see how I can help.<br />
* Infrastructure, Web, E-Commerce<br />
* I don't have a strong preference about that. i never visited a hackathon before so i think i have to see how everything works when i am at the hackathon.<br />
* also things related to DICOM file archiving.<br />
* Ontology Editor, 3d Tree Canvas,...<br />
* postgresql-crud (to be announced), monad-classes, wai-predicates, anything interesting.<br />
* Getting rid of cabal hell. Doing DevOps stuff and compiling a working tool chain. Continue "LYAH"<br />
* Parsing tools. <br />
* language-swift: Starting as new project. Library to analyse and generate code for Apple's new programming language Swift. Similar to language-c and hopefully at some point the base for something hlint like for Swift. <br />
<br />
# Project Proposal for the haskell Hackathon Berlin 2015<br />
<br />
A Testcase generator for system tests.<br />
With as few lines as possible generate as most test scripts as possible, part test-cases are combinable.<br />
Language for generating the testcases: haskell, with embedded DSL.<br />
Language of the test scripts: ruby, python, perl, c++, ... (it depends)<br />
test target: an embedded device, a mail server, a web-service, ..., but at first no GUI.<br />
<br />
The existing example:<br />
There exists a test generating tool named ""tedeso"" by Siemens.<br />
Tedeso has 2 major building blocks: <br />
- variables/instances of classes with attributes: The attributes can have different values and the test script is executed with all instances. Each test script uses one instance.<br />
- branching: do this or do this or do this: the different test scripts are generated by following the different pathes. Each test script is one path.<br />
- a GUI, with which you can draw a testcase. But this can be omitted. In my point of view, it is not practical. A test script written in a good embedded dsl is better readable and better comparable with older versions.<br />
<br />
The haskell testcase generator shall go beyond Tedeso:<br />
It shall easily be possible to combine (parts of) testcases to build bigger ones. Haskell is good for that purpose, because the part test scripts are functions, without side effects.<br />
The testcases could have attributes, which say something of the condition or state that is fulfilled or reached by the (part-)test script.<br />
<br />
Bigger challenges:<br />
<br />
1.) If the attributes of the part test scripts ar cleverly chosen, can they form a kind of formal specification of the system under test?<br />
<br />
2.)If someone asks, possibly after years, what the system under test does under certain circumstances, can you ask the set of your test programs what happens ? Possibly: "" Yes, we have tested it in 2015, and the test ran ok!"", without actually running the test, just by typing the specification of the question to your test environment ?<br />
A solution could be a database of test cases or a analyzation of the test programs (perhaps with template haskell? I do not know much about it.)<br />
<br />
3.)Can one make a test case by saying: ""<br />
a.) Go to state X, in any possible way. <br />
b.) Do this special. (perhaps test a new requirement, that is just implemented)<br />
c.) After that you are in state Y. Do some arbitrarily chosen part-testcases begining with that state Y."" <br />
<br />
The 2 major building blocks of tedeso, variables and branching, are easily done with haskell. That have I already programmed, as a beginner in haskell, who i am. But there seems to be much possible in testing with haskell. <br />
For Open source programs there is the need for good system test tools. When I look at open source source code, I do not find many test cases, if any. Perhaps could a easy usable system test environment improve the quality of open source software.<br />
<br />
# Pedro's working topics<br />
<br />
I plan to be mostly working on Chordify-related stuff. But I will also discuss some GHC Generics stuff with Gabor and Andres, and I might have a look at some of the tickets on this list: https://ghc.haskell.org/trac/ghc/wiki/PedrosTickets<br />
<br />
In general, if you're interested in some GHC hacking, I can try to help you get along the source code.</div>Dreixelhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Generic_programming&diff=57558Applications and libraries/Generic programming2014-02-12T13:48:08Z<p>Dreixel: /* Work Plan */</p>
<hr />
<div>{{unknown copyright}}<br />
<br />
<br />
==Recommended libraries==<br />
See [[Generics]]<br />
<br />
<br />
== Old discussions ==<br />
=== Common library for generic programming ===<br />
<br />
Johan Jeuring and Andres Loeh [http://article.gmane.org/gmane.comp.lang.haskell.general/14304/ announced] (in 2006) an initiative to design a common library for generic programming, which should work together with most of the Haskell compilers, and for which they hope to guarantee support for generics in Haskell into the future. If you want to get involved (or just want to see the discussion), you can subscribe to [http://www.haskell.org/mailman/listinfo/generics the generics mailing list] (mostly idle since ~2010). Check the [http://haskell.org/haskellwiki/Research_papers/Generics Haskell research wiki] for some background on generics.<br />
<br />
==== Work Plan ====<br />
<br />
We have identified a number of approaches that are potential candidates to a generic programming library:<br />
<br />
<ul><br />
<li><p>[[/Lightweight|A Lightweight Implementation Generics and Dynamics]]</p></li><br />
<li><p>[[/SyB| SYB (and variants)]]</p></li><br />
<li><p>[[/Strafunski| Strafunski]]</p></li><br />
<li><p>Generics for the Masses</p></li><br />
<li><p>Generics as a library</p></li><br />
<li><p>[[/Smash|Smash your Boilerplate]]</p></li><br />
<li><p>RepLib</p></li><br />
<li><p>Extensible superclasses</p></li><br />
<li><p>Almost compositional functions</p></li><br />
</ul><br />
<br />
At the moment we are discussing the advantages and disadvantages of the different approaches. Each approach is roughly two weeks under discussion and the results will be published in this Wiki Page. There is also a darcs repository where you can find some code that we are collecting. For retrieving this code do:<br />
<br />
> darcs get http://code.haskell.org/generics/<br />
<br />
The template that we are using to summarise the different approaches can be found [[/Template|here]].<br />
<br />
===Benchmark suite===<br />
We have developed a benchmark suite that tests the expressiveness of different generic programming libraries. For more information go to: [[GPBench]].</div>Dreixelhttps://wiki.haskell.org/index.php?title=Implementations&diff=56968Implementations2013-10-09T14:44:21Z<p>Dreixel: /* Hugs */ is an interpreter, not a compiler, and it's very debatable whether it's still the best system for newcomers</p>
<hr />
<div>Below you find a list of all Haskell implementations. The recommend way to install Haskell on your computer is through the the [http://hackage.haskell.org/platform/ Haskell Platform].<br />
<br />
<br />
== Haskell 2010 == <br />
<br />
=== Glasgow Haskell Compiler (GHC) ===<br />
[[GHC]] is an optimising compiler for Haskell, providing many language extensions. GHC is the de facto standard compiler if you want fast code. GHC is written in Haskell (plus extensions), and its size and complexity mean that it is less portable than Hugs, it runs more slowly, and it needs more memory. However, the programs it produces run ''much'' faster.<br />
<br />
There is also an interactive environment, GHCi, which is like Hugs but supports interactive loading of compiled code. GHC provides profiling for time and space, and supports concurrent and parallel programming. It is available for most common platforms, including Windows, Mac OS X, and several Unix variants (Linux, *BSD, Solaris).<br />
<br />
The GHC team recommends installing the [http://hackage.haskell.org/platform/ Haskell Platform] to get GHC.<br />
<br />
<br />
== Haskell 98 ==<br />
<br />
=== Utrecht Haskell Compiler (UHC) ===<br />
[http://www.cs.uu.nl/wiki/UHC UHC] is a Haskell implementation from Utrecht University. UHC supports almost all Haskell98 features plus many experimental extensions. The compiler runs on Mac OS X, Windows (cygwin), and various Unix flavors.<br />
<br />
Features include: Multiple backends, including a bytecode interpreter backend and a whole-program analysis backend based on GRIN. Experimental language extensions, some of which have not been implemented before.<br />
<br />
UHC is implemented using [[Attribute grammar|attribute grammars]], and due to an aspect-oriented internal organisation is ideally suited for experimenting with language extensions.<br />
<br />
On April 18, 2009 UHC was [http://www.cs.uu.nl/wiki/UHC/Announce announced] at the 5th Haskell Hackathon in Utrecht.<br />
<br />
=== Jhc Haskell Compiler ===<br />
[http://repetae.net/computer/jhc/ Jhc] is an experimental compiler with a goal of testing new optimization methods and exploring the design space of Haskell implementations.<br />
<br />
<br />
== Haskell Dialects ==<br />
<br />
=== Disciple ===<br />
[http://disciple.ouroborus.net Disciple] is a dialect of Haskell that uses strict evaluation as the default and supports destructive update of arbitrary data structures. Disciple includes region, effect and closure typing, and this extra information provides a handle on the operational behaviour of code that isn't available in other languages. Programs can be written in either a pure/functional or effectful/imperative style, and one of our goals is to provide both styles coherently in the same language. Our compiler is still in the "research prototype" stage, but will compile programs if you are nice to it.<br />
<br />
<br />
== Unmaintained ==<br />
<br />
=== LHC ===<br />
[http://lhc.seize.it/ LHC] initially started off as a fork of JHC, but changed toward being an alternative GHC backend, performing aggressive whole-program analysis on GHC's external core language.<br />
<br />
=== Hugs ===<br />
[[Hugs]] is a small, portable Haskell interpreter written in C runs on almost any machine. Hugs is best used as a Haskell program development system: it boasts extremely fast source code interpretation, supports incremental interpretation, and has the convenience of an interactive interpreter (within which one can move from module to module to test different portions of a program). However, being an interpreter, it does not nearly match the run-time performance of, for example, GHC, nhc98, or HBC. Hugs 98 is conformant with Haskell 98. Available for all Unix platforms including Linux, DOS, Windows 3.x, and Win 32 (Windows 95, Win32s, NT) and Macintoshes. It has many libraries including Win32 libraries, a foreign interface mechanism to facilitate interoperability with C, and the Windows version has a graphical user interface called [[WinHugs]]. Explanations of some common Hugs error messages and their causes can be found on [http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/errors.html Simon Thompson's page].<br />
<br />
=== nhc98 ===<br />
[http://www.haskell.org/nhc98/ nhc98] is a small, easy to install, standards-compliant Haskell 98 compiler. It works only on 32-bit machines. It provides some advanced kinds of heap profiles not found in any other Haskell compiler. It produces medium-fast code, and compilation is itself quite fast. The compiler stresses the saving of space, that is, it produces small programs requiring comparatively little space at runtime (and it is itself much smaller than the other compilers). It is available for all Unix-like platforms (including Mac OS X, Cygwin/Windows, Linux, Solaris, *BSD, AIX, HP-UX, Ultrix, IRIX, etc.). It is written in Haskell 98, but can be quickly and easily bootstrapped from C sources.<br />
<br />
=== York Haskell Compiler (YHC) ===<br />
[[Yhc]] is a fork of [http://www.haskell.org/nhc98/ nhc98], with the goals of being simpler, more portable, more efficient and integrating [[Hat]] support.<br />
<br />
=== [http://www.cs.chalmers.se/~augustss/hbc/hbc.html '''HBI''' and '''HBC'''], Chalmers' Haskell Interpreter and Compiler ===<br />
The Chalmers Haskell-B compiler 0.9999.5c implements Haskell 98, as well as some extensions. It is written by Lennart Augustsson, and based on the classic LML compiler by Augustsson and Johnsson. The interpreter can also load code compiled with HBC. There has been no official release for the last few years and the support level is pretty low, but the compiler exists and can be used. Unfortunately the web-pages and the documentation has not been updated the last few years! You can download an unofficial [http://haskell.org/hbc/hbc-2004-06-29.src.tar.gz snapshot of the sources] and the corresponding [http://haskell.org/hbc/hbc-2004-06-29.bin-i386-linux.tar.gz x86 Linux binaries] (based on [http://www.cs.chalmers.se/pub/users/hallgren/Alfa/Haskell/ snapshots] from Thomas Hallgren and Magnus Carlsson).<br />
<br />
=== Helium ===<br />
[http://www.cs.uu.nl/wiki/Helium Helium] is a functional programming language and a compiler designed especially for teaching Haskell. Quality of the error messages has been the main concern both in the choice of the language features and in the implementation of the compiler. The language is a subset of the Haskell language. The most notable difference with Haskell is the absence of overloading. The compiler keeps track of a lot of information to produce informative messages.<br />
<br />
=== Yale Haskell ===<br />
[http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/haskell/0.html Yale Haskell 2.05], an early implementation of Haskell in Lisp. See an early [http://groups.google.com/group/comp.lang.functional/msg/5b929ac0223a6212?dmode=source&hl=en release announcement]<br />
<br />
=== The Brisk compiler ===<br />
A product of the [http://www.cs.bris.ac.uk/Research/LanguagesArchitecture/brisk.html BRISK project] at the University of Bristol investigating the further use of functional programming in systems-level software development. Version [http://www.cs.bris.ac.uk/~ian/Functional/brisk.tgz 0.08] partially implements an early version of Haskell.<br />
<br />
== Comparison of Implementations ==<br />
* Comparison of [http://mirror.seize.it/report.html speed and memory usage] of several Haskell implementations (February 2011). This page also shows how many samples compile/run correctly.<br />
<br />
* A [http://stackoverflow.com/questions/4084790/compilers-for-haskell stackoverflow discussion] of several implementations.<br />
<br />
<br />
[[Category:Implementations| ]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=54551GHC.Generics2012-10-25T08:44:50Z<p>Dreixel: /* Limitations */</p>
<hr />
<div>GHC 7.2 includes improved support for ''datatype-generic programming'' through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
We cannot derive <tt>Generic</tt> instances for:<br />
* Datatypes with a context;<br />
* Existentially-quantified datatypes;<br />
* GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=54550GHC.Generics2012-10-25T08:44:33Z<p>Dreixel: </p>
<hr />
<div>GHC 7.2 includes improved support for ''datatype-generic programming'' through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=45356GHC.Generics2012-04-21T11:10:20Z<p>Dreixel: </p>
<hr />
<div>GHC 7.2 includes improved support for ''datatype-generic programming'' through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=45355GHC.Generics2012-04-21T11:09:53Z<p>Dreixel: </p>
<hr />
<div>GHC 7.2 includes new support for ''datatype-generic programming'' through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=Generics&diff=45354Generics2012-04-21T11:08:39Z<p>Dreixel: </p>
<hr />
<div>''Datatype-generic programming'', also frequently just called ''generic programming'' or ''generics'' in Haskell, is a form of abstraction that allows defining functions that can operate on a large class of datatypes. In this page we summarise a number of popular approaches to generic programming that are often used with GHC. For a more in-depth introduction to generic programming in general, have a look at Gibbon's [http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/dgp.pdf Datatype-Generic Programming], or the [http://dreixel.net/research/pdf/lgph.pdf Libraries for Generic Programming] paper.<br />
<br />
== What is generic programming? ==<br />
<br />
Haskell is a polymorphic language. This means that you can have a single datatype for lists:<br />
<haskell><br />
data List a = Nil | Cons a (List a)<br />
</haskell><br />
These lists can contain any type of information, such as integers, Booleans, or even other lists. Since the length of a list does not depend on the type of its elements, there is also a single definition for list length:<br />
<haskell><br />
length :: List a -> Int<br />
length Nil = 0<br />
length (Cons _ t) = 1 + length t<br />
</haskell><br />
<br />
However, it's not only lists that have length. Consider a datatype for trees:<br />
<haskell><br />
data Tree a = Leaf | Bin a (Tree a) (Tree a)<br />
</haskell><br />
You can also compute the length of a tree (or its size, if you want), by recursively traversing the tree and counting the number of elements. Generic programming allows to define a ''single'' length function, that can operate on lists, trees, and many other datatypes. This reduces code duplication and makes the code more robust to changes, because you can change your datatypes without needing to adapt the generic functions that operate on them.<br />
<br />
We now look at some approaches to generic programming in Haskell.<br />
<br />
== GHC.Generics ==<br />
<br />
The <hask>GHC.Generics</hask> module, available since GHC version 7.2, allows you to easily define classes with methods for which no implementation is necessary, similarly to <hask>Show</hask>, for instance. It's described in a [[GHC.Generics|separate wiki page]].<br />
<br />
== SYB ==<br />
<br />
Scrap Your Boilerplate (SYB), available in GHC since 6.0, is an earlier approach to generic programming, particularly well suited for traversals and transformations over large trees. It has its own [http://www.cs.uu.nl/wiki/GenericProgramming/SYB wiki page].<br />
<br />
== Uniplate ==<br />
<br />
Uniplate is available as a [http://hackage.haskell.org/package/uniplate library on Hackage]. It is similar in nature to SYB, but uses simpler types. For more information [http://community.haskell.org/~ndm/uniplate/ see its webpage].<br />
<br />
== Multirec ==<br />
<br />
Multirec is a library for generic programming with fixed points, supporting mutually recursive families of datatypes, and allowing functionality such as folds or the zipper. For more information, [http://www.cs.uu.nl/wiki/GenericProgramming/Multirec see its webpage].</div>Dreixelhttps://wiki.haskell.org/index.php?title=Generics&diff=45353Generics2012-04-21T08:36:53Z<p>Dreixel: </p>
<hr />
<div>''Datatype-generic programming'', also frequently just called ''generic programming'' or ''generics'' in Haskell, is a form of abstraction that allows defining functions that can operate on a large class of datatypes. In this page we summarise a number of popular approaches to generic programming that are often used with GHC. For a more in-depth introduction to generic programming in general, have a look at Gibbon's [http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/dgp.pdf Datatype-Generic Programming], or the [http://dreixel.net/research/pdf/lgph.pdf Libraries for Generic Programming] paper.<br />
<br />
== What is generic programming? ==<br />
<br />
Haskell is a polymorphic language. This means that you can have a single datatype for lists:<br />
<haskell><br />
data List a = Nil | Cons a (List a)<br />
</haskell><br />
These lists can contain any type of information, such as integers, Booleans, or even other lists. Since the length of a list does not depend on the type of its elements, there is also a single definition for list length:<br />
<haskell><br />
length :: List a -> Int<br />
length Nil = 0<br />
length (Cons _ t) = 1 + length t<br />
</haskell><br />
<br />
However, it's not only lists that have length. Consider a datatype for trees:<br />
<haskell><br />
data Tree a = Leaf | Bin a (Tree a) (Tree a)<br />
</haskell><br />
You can also compute the length of a tree (or its size, if you want), by recursively traversing the tree and counting the number of elements. Generic programming allows to define a ''single'' length function, that can operate on lists, trees, and many other datatypes. This reduces code duplication and makes the code more robust to changes, because you can change your datatypes without needing to adapt the generic functions that operate on them.<br />
<br />
We now look at some approaches to generic programming in Haskell.<br />
<br />
<br />
== GHC.Generics ==<br />
<br />
The <hask>GHC.Generics</hask> module, available since GHC version 7.2, allows you to easily define classes with methods for which no implementation is necessary, similarly to <hask>Show</hask>, for instance. It's described in a [[GHC.Generics|separate wiki page]].<br />
<br />
== SYB ==<br />
<br />
== Uniplate ==<br />
<br />
== Multirec ==</div>Dreixelhttps://wiki.haskell.org/index.php?title=Generics&diff=45352Generics2012-04-21T08:31:41Z<p>Dreixel: </p>
<hr />
<div>''Datatype-generic programming'', also frequently just called ''generic programming'' or ''generics'' in Haskell, is a form of abstraction that allows defining functions that can operate on a large class of datatypes. In this page we summarise a number of popular approaches to generic programming that are often used with GHC. For a more in-depth introduction to generic programming in general, have a look at Gibbon's [http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/dgp.pdf Datatype-Generic Programming], or the [http://dreixel.net/research/pdf/lgph.pdf Libraries for Generic Programming] paper.<br />
<br />
== What is generic programming? ==<br />
<br />
Haskell is a polymorphic language. This means that you can have a single datatype for lists:<br />
<haskell><br />
data List a = Nil | Cons a (List a)<br />
</haskell><br />
These lists can contain any type of information, such as integers, Booleans, or even other lists. Since the length of a list does not depend on the type of its elements, there is also a single definition for list length:<br />
<haskell><br />
length :: List a -> Int<br />
length Nil = 0<br />
length (Cons _ t) = 1 + length t<br />
</haskell><br />
<br />
However, it's not only lists that have length. Consider a datatype for trees:<br />
<haskell><br />
data Tree a = Leaf | Bin a (Tree a) (Tree a)<br />
</haskell><br />
You can also compute the length of a tree (or its size, if you want), by recursively traversing the tree and counting the number of elements. Generic programming allows to define a ''single'' length function, that can operate on lists, trees, and many other datatypes. This reduces code duplication and makes the code more robust to changes, because you can change your datatypes without needing to adapt the generic functions that operate on them.<br />
<br />
We now look at some approaches to generic programming in Haskell.<br />
<br />
<br />
== GHC.Generics ==<br />
<br />
See [[GHC.Generics]].<br />
<br />
== SYB ==<br />
<br />
== Uniplate ==<br />
<br />
== Multirec ==</div>Dreixelhttps://wiki.haskell.org/index.php?title=Generics&diff=45350Generics2012-04-21T08:01:51Z<p>Dreixel: Placeholder page</p>
<hr />
<div>This page will describe multiple generic programming approaches that can be used with GHC. For now, there's only documentation for [[GHC.Generics]].</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=45346GHC.Generics2012-04-21T08:00:59Z<p>Dreixel: Generics moved to GHC.Generics: Generalizing the Generics page to mention other libraries too.</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=Generics&diff=45347Generics2012-04-21T08:00:59Z<p>Dreixel: Generics moved to GHC.Generics: Generalizing the Generics page to mention other libraries too.</p>
<hr />
<div>#REDIRECT [[GHC.Generics]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=Talk:GHC.Generics&diff=45348Talk:GHC.Generics2012-04-21T08:00:59Z<p>Dreixel: Talk:Generics moved to Talk:GHC.Generics: Generalizing the Generics page to mention other libraries too.</p>
<hr />
<div>Why does the definition of (:+:) use the pipe character "|", but the definition of (:*:) uses the ":*:" operator?<br />
<br />
<br />
Is that a typo (copied from http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/generic-programming.html), or is there a reason for the difference?<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
<br />
<br />
Is it just fallout from of "asymmetry" in Haskell language spec, <br />
where Sum types need the pipe to separate the alternations, <br />
but Product types are written with the factors simply adjacent without a separator? (and then it looks pretty to use infix constructor "+351916292294" instead of a prefix constructor "P")<br />
<br />
----<br />
<br />
Yes, the pipe separates different constructors of a datatype, and the (:*:) is an infix constructor.<br />
<br />
--[[User:Dreixel|dreixel]] 17:39, 3 March 2012 (UTC)</div>Dreixelhttps://wiki.haskell.org/index.php?title=Talk:Generics&diff=45349Talk:Generics2012-04-21T08:00:59Z<p>Dreixel: Talk:Generics moved to Talk:GHC.Generics: Generalizing the Generics page to mention other libraries too.</p>
<hr />
<div>#REDIRECT [[Talk:GHC.Generics]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/DHD_Program&diff=45291DHD UHac/DHD Program2012-04-17T14:09:43Z<p>Dreixel: </p>
<hr />
<div>__NOTOC__<br />
<br />
This is the current program for the Dutch HUG Day. It may still change.<br />
<br />
{| class="wikitable"<br />
! Time<br />
! Title<br />
! Speaker<br />
|-<br />
| 9:30<br />
| colspan="2" | ''Coffee and Tea''<br />
|-<br />
| 10:00<br />
| Welcome<br />
| Sean Leather, Stef Joosten<br />
|-<br />
| 10:15<br />
| [[#websockets|Supporting Different Versions of the WebSockets Protocol]]<br />
| Jasper Van der Jeugt<br />
|-<br />
| 10:45<br />
| [[#hesselink|Building Your Own Haskell Ecosystem]]<br />
| Erik Hesselink<br />
|-<br />
| 11:15<br />
| [[#pascal|Model Checking Abstract Syntax Trees]]<br />
| Pascal Hof<br />
|-<br />
| 11:45<br />
|colspan="2"| ''Lightning Talks''<br />
|-<br />
|<br />
| [[#dotfs|DotFS - or How Fred Solved His Config Clutter]]<br />
| Paul van der Walt, Sjoerd Timmer<br />
|-<br />
|<br />
| [[#gruze|Snap and Gruze]]<br />
| Kevin Jardine<br />
|-<br />
|<br />
| [[#case-study|Invitation to Participate in a Functional Programming Case Study]]<br />
| Jurriaan Hage<br />
|-<br />
| 12:15<br />
| colspan="2" | ''Lunch (provided by Ordina)''<br />
|-<br />
| 13:15<br />
| [[#practice|Haskell in Practice: How Haskell Has Been Used in a (Paid) IT Project]]<br />
| Stef Joosten, Martijn Schrage<br />
|-<br />
| 13:45<br />
| [[#fclabels|fclabels: First Class Record Labels for Haskell]]<br />
| Sebastiaan Visser<br />
|-<br />
| 14:15<br />
| [[#kinds|GHC 7.6, more well-typed than ever]]<br />
| José Pedro Magalhães<br />
|-<br />
| 14:45<br />
|colspan="2"| ''Lightning Talks''<br />
|-<br />
|<br />
| [[#holes|Holes in GHC]]<br />
| Thijs Alkemade<br />
|-<br />
|<br />
| [[#regex-applicative|Applicative Regular Expressions]]<br />
| Roman Cheplyaka<br />
|-<br />
|<br />
|colspan="2"| ''Available''<br />
|-<br />
| 15:15<br />
| Closing<br />
| Jurriën Stutterheim<br />
|-<br />
| 15:30<br />
|colspan="2"| ''Depart for UHac''<br />
|}<br />
<br />
== Summaries ==<br />
<br />
=== <span id="websockets"></span>Supporting Different Versions of the WebSockets Protocol ===<br />
<br />
Jasper Van der Jeugt (Ghent)<br />
<br />
The Haskell websockets library allows you to write WebSocket-enabled<br />
servers in Haskell, bidirectional communication with the browser.<br />
However, browsers and their related specifications change fast, and<br />
there are different versions of the WebSockets protocol. This talk<br />
discusses a type-safe technique which disallows the programmer from<br />
using primitives not available in the chosen version, while still<br />
allowing the latest features.<br />
<br />
=== <span id="hesselink"></span>Building Your Own Haskell ecosystem ===<br />
<br />
Erik Hesselink (Silk)<br />
<br />
When you develop a lot of different Haskell packages that work together, managing all these packages and their versions can be difficult. In this talk, I'll explain how we deal with this at Silk. I will show how to use Hackage 2.0 to build your own internal package repository, how to use cabal-dev to manage installed packages, and show a tool for bumping package versions. Together, this makes working on large amounts of packages with multiple people much easier.<br />
<br />
=== <span id="pascal"></span>Model Checking Abstract Syntax Trees ===<br />
<br />
Pascal Hof (TU Dortmund)<br />
<br />
Model checking turned out to be a useful tool for the analysis of programs. Usually one transforms abstract syntax trees to control flow graphs, which offer a abstract representation of program behavior. Whenever one is not focused on program behavior but on structural properties of the program (e.g. semantic analysis of a compiler), model checking the abstract syntax tree comes in handy. My talk introduces a problem, which can be solved using model checking abstract syntax trees. Additionally, different approaches for a implementation will be discussed.<br />
<br />
=== <span id="dotfs"></span>DotFS - or How Fred Solved His Config Clutter ===<br />
<br />
Paul van der Walt (UU), Sjoerd Timmer (UU)<br />
<br />
Everyone who has more than one account on Linux/Unix/OS X systems knows how hard is can be to keep track of all the different config files in your home directory. <tt>.vimrc</tt>, <tt>.muttrc</tt>, <tt>.hgrc</tt>, <tt>.screenrc</tt>, <tt>.bashrc</tt>, and <tt>.xinitrc</tt> are just a few, but we're sure you can come up with many more yourself. Imagine how wonderful your life could be if you just had an easy tool to keep track of different versions of all these files on all your machines. We argue that traditional version control systems on their own are not up the task and we provide an alternative.<br />
<br />
=== <span id="gruze"></span>Snap and Gruze ===<br />
<br />
Kevin Jardine<br />
<br />
Developing an astronomy application using Snap and an experimental entity-attribute-value store for Haskell.<br />
<br />
=== <span id="case-study"></span>Invitation to Participate in a Functional Programming Case Study ===<br />
<br />
Jurriaan Hage (UU)<br />
<br />
I want to invite you to participate in an experiment in Haskell.<br />
In this experiment we are going to pit HaRe (the Haskell Refactorer)<br />
against Holmes (my plagiarism detector). The goal is to find out how much<br />
time somebody needs to refactor a Haskell program into something that<br />
is not recognizable by Holmes as plagiarism. We shall be looking at<br />
two groups of study: experienced programmers (we shall pretend they<br />
are paid for by newbies to make their assignments for them, and to do<br />
so without starting from scratch), and the newbies themselves.<br />
This experiment is a collaboration with Simon Thompson of Kent.<br />
He will take charge of the newbies, my task is to perform the experiment<br />
with experienced Haskell programmers, which is why I am now seeking for<br />
participants.<br />
<br />
=== <span id="practice"></span>Haskell in Practice: How Haskell Has Been Used in a (Paid) IT Project ===<br />
<br />
Stef Joosten (Ordina), Martijn Schrage (Oblomov Systems)<br />
<br />
This presentation shows how new thinking helps the judiciary to gain control over and to reduce cost in a landscape of many different IT systems that serve the courts of law in the Netherlands.<br />
<br />
Although Haskell plays a role outside the limelight, the results have become possible because of a tool, Ampersand, which has been built in Haskell.<br />
<br />
The presentation is accompanied by a brief demonstration.<br />
<br />
=== <span id="fclabels"></span>fclabels: First Class Record Labels for Haskell ===<br />
<br />
Sebastiaan Visser (Silk)<br />
<br />
Haskell's record system for algebraic datatypes uses labels as accessors for fields within constructors. Record labels can be used for both selection and modification of individual fields within value, but only selection can be composed in a natural way. The special syntax for updates makes composing modifications very cumbersome. The fclabels package tries to solve this problem by implementing field accessors as first class Haskell values instead of special syntax. Labels are implemented as lenses and can easily be composed for both selection and modification. To avoid boilerplate labels can be derived using Template Haskell. This talk will give a brief introduction into the usage of the library and will show a bit of the inner workings as a bridge to future <br />
extensions.<br />
<br />
=== <span id="kinds"></span>GHC 7.6, more well-typed than ever ===<br />
<br />
José Pedro Magalhães (UU)<br />
<br />
With each new version, GHC brings new and exciting type-level features to the<br />
Haskell language. In this talk we look at some upcoming features for GHC 7.6:<br />
data kinds, kind polymorphism, type-level literals, and deferred type errors.<br />
We show through some example programs how to take advantage of the new features,<br />
and what possibilities they open for Haskell programmers.<br />
<br />
=== <span id="holes"></span>Holes in GHC ===<br />
<br />
Thijs Alkemade (UU)<br />
<br />
This will be a demonstration of work-in-progress on adding holes for type-based debugging with GHC. See the [http://hackage.haskell.org/trac/ghc/wiki/Holes GHC Trac page] for details.<br />
<br />
=== <span id="regex-applicative">Applicative Regular Expressions</span> ===<br />
<br />
Roman Cheplyaka<br />
<br />
In this short talk I am going to describe the<br />
[https://github.com/feuerbach/regex-applicative regex-applicative] project:<br />
* what it is about<br />
* how it compares to other parsing combinator libraries<br />
* its current state and unsolved problems<br />
<br />
I'll be glad to accept any help<br />
[http://www.haskell.org/haskellwiki/DHD_UHac/Projects#regex-applicative during UHac].</div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/DHD_Program&diff=45214DHD UHac/DHD Program2012-04-10T10:23:24Z<p>Dreixel: </p>
<hr />
<div>__NOTOC__<br />
<br />
This is the current program for the Dutch HUG Day. It may still change.<br />
<br />
{| class="wikitable"<br />
! Time<br />
! Title<br />
! Speaker<br />
|-<br />
| 9:30<br />
| colspan="2" | ''Coffee and Tea''<br />
|-<br />
| 10:00<br />
| Welcome<br />
| Sean Leather, Stef Joosten<br />
|-<br />
| 10:15<br />
| [[#websockets|WebSockets]]<br />
| Jasper Van der Jeugt<br />
|-<br />
| 10:45<br />
| [[#hesselink|''TBD'']]<br />
| Erik Hesselink<br />
|-<br />
| 11:15<br />
| [[#pascal|''TBD'']]<br />
| Pascal Hof<br />
|-<br />
| 11:45<br />
|colspan="2"| ''Lightning Talks''<br />
|-<br />
|<br />
| [[#dotfs|DotFS]]<br />
| Paul van der Walt, Sjoerd Timmer<br />
|-<br />
|<br />
| [[#gruze|Snap and Gruze]]<br />
| Kevin Jardine<br />
|-<br />
|<br />
| [[#case-study|Case Study Invitation]]<br />
| Jurriaan Hage<br />
|-<br />
| 12:15<br />
| colspan="2" | ''Lunch (Provided by Ordina)''<br />
|-<br />
| 13:15<br />
| [[#practice|Haskell in Practice]]<br />
| Stef Joosten, Martijn Schrage<br />
|-<br />
| 13:45<br />
| [[#fclabels|fclabels]]<br />
| Sebastiaan Visser<br />
|-<br />
| 14:15<br />
| [[#jpm|''TBD'']]<br />
| José Pedro Magalhães<br />
|-<br />
| 14:45<br />
|colspan="2"| ''Lightning Talks''<br />
|-<br />
|<br />
| [[#holes|Holes in GHC]]<br />
| Thijs Alkemade<br />
|-<br />
|<br />
| [[#regex-applicative|Applicative Regular Expressions]]<br />
| Roman Cheplyaka<br />
|-<br />
|<br />
| ''Available''<br />
|<br />
|-<br />
| 15:15<br />
| Closing<br />
| Jurriën Stutterheim<br />
|-<br />
| 15:30<br />
| Depart for UHac<br />
|<br />
|}<br />
<br />
== Summaries ==<br />
<br />
=== <span id="websockets"></span>Supporting Different Versions of the WebSockets Protocol ===<br />
<br />
Jasper Van der Jeugt (Ghent)<br />
<br />
The Haskell websockets library allows you to write WebSocket-enabled<br />
servers in Haskell, bidirectional communication with the browser.<br />
However, browsers and their related specifications change fast, and<br />
there are different versions of the WebSockets protocol. This talk<br />
discusses a type-safe technique which disallows the programmer from<br />
using primitives not available in the chosen version, while still<br />
allowing the latest features.<br />
<br />
=== <span id="hesselink"></span>''TBD'' ===<br />
<br />
Erik Hesselink (Silk)<br />
<br />
To be determined.<br />
<br />
=== <span id="pascal"></span>''TBD'' ===<br />
<br />
Pascal Hof (TU Dortmund)<br />
<br />
To be determined.<br />
<br />
=== <span id="dotfs"></span>DotFS - Or How Fred Solved His Config Clutter ===<br />
<br />
Paul van der Walt (UU), Sjoerd Timmer (UU)<br />
<br />
Everyone who has more than one account on Linux/Unix/OS X systems knows how hard is can be to keep track of all the different config files in your home directory. <tt>.vimrc</tt>, <tt>.muttrc</tt>, <tt>.hgrc</tt>, <tt>.screenrc</tt>, <tt>.bashrc</tt>, and <tt>.xinitrc</tt> are just a few, but we're sure you can come up with many more yourself. Imagine how wonderful your life could be if you just had an easy tool to keep track of different versions of all these files on all your machines. We argue that traditional version control systems on their own are not up the task and we provide an alternative.<br />
<br />
=== <span id="gruze"></span>Snap and Gruze ===<br />
<br />
Kevin Jardine<br />
<br />
Snap and Gruze. Developing an astronomy application using Snap and an experimental entity-attribute-value store for Haskell.<br />
=== <span id="case-study"></span>Invitation to Participate in a Functional Programming Case Study ===<br />
<br />
Jurriaan Hage (UU)<br />
<br />
I want to invite you to participate in an experiment in Haskell.<br />
In this experiment we are going to pit HaRe (the Haskell Refactorer)<br />
against Holmes (my plagiarism detector). The goal is to find out how much<br />
time somebody needs to refactor a Haskell program into something that<br />
is not recognizable by Holmes as plagiarism. We shall be looking at<br />
two groups of study: experienced programmers (we shall pretend they<br />
are paid for by newbies to make their assignments for them, and to do<br />
so without starting from scratch), and the newbies themselves.<br />
This experiment is a collaboration with Simon Thompson of Kent.<br />
He will take charge of the newbies, my task is to perform the experiment<br />
with experienced Haskell programmers, which is why I am now seeking for<br />
participants.<br />
<br />
=== <span id="practice"></span>Haskell in Practice: How Haskell Has Been Used in a (Paid) IT Project. ===<br />
<br />
Stef Joosten (Ordina), Martijn Schrage (Oblomov Systems)<br />
<br />
This presentation shows how new thinking helps the judiciary to gain control over and to reduce cost in a landscape of many different IT systems that serve the courts of law in the Netherlands.<br />
<br />
Although Haskell plays a role outside the limelight, the results have become possible because of a tool, Ampersand, which has been built in Haskell.<br />
<br />
The presentation is accompanied by a brief demonstration.<br />
<br />
=== <span id="fclabels"></span>fclabels: First Class Record Labels for Haskell ===<br />
<br />
Sebastiaan Visser (Silk)<br />
<br />
Haskell's record system for algebraic datatypes uses labels as accessors for fields within constructors. Record labels can be used for both selection and modification of individual fields within value, but only selection can be composed in a natural way. The special syntax for updates makes composing modifications very cumbersome. The fclabels package tries to solve this problem by implementing field accessors as first class Haskell values instead of special syntax. Labels are implemented as lenses and can easily be composed for both selection and modification. To avoid boilerplate labels can be derived using Template Haskell. This talk will give a brief introduction into the usage of the library and will show a bit of the inner workings as a bridge to future extensions.<br />
<br />
=== <span id="holes"></span>Holes in GHC ===<br />
<br />
Thijs Alkemade (UU)<br />
<br />
This will be a demonstration of work-in-progress on adding holes for type-based debugging with GHC. See the [http://hackage.haskell.org/trac/ghc/wiki/Holes GHC Trac page] for details.<br />
<br />
=== <span id="regex-applicative">Applicative Regular Expressions</span> ===<br />
<br />
Roman Cheplyaka<br />
<br />
In this short talk I am going to describe the<br />
[https://github.com/feuerbach/regex-applicative regex-applicative] project:<br />
* what it is about<br />
* how it compares to other parsing combinator libraries<br />
* its current state and unsolved problems<br />
<br />
I'll be glad to accept any help<br />
[http://www.haskell.org/haskellwiki/DHD_UHac/Projects#regex-applicative during UHac].</div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=45176DHD UHac/Projects2012-04-06T09:56:11Z<p>Dreixel: /* Project Name */</p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Write a description of other GP libs in [http://www.haskell.org/haskellwiki/Generics the Haskell wiki]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5939 #5939]<br />
* Think about [http://hackage.haskell.org/trac/ghc/ticket/5936 #5936]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
=== Standard algorithms ===<br />
<br />
Objective point of this project is to implement or improve<br />
some standard algorithms like suffix arrays, z-function,<br />
cartesian trees, dijkstra algorithms which lack in standard library.<br />
<br />
Interested:<br />
* Victor Denisov<br />
<br />
Links:<br />
* https://github.com/haskellization/algorithms/wiki<br />
<br />
<br />
=== regex-applicative ===<br />
<br />
To learn about the project, see [https://github.com/feuerbach/regex-applicative/blob/master/README.md the README]. There will also be [http://www.haskell.org/haskellwiki/DHD_UHac/DHD_Program#regex-applicative a short talk] about it on the first day.<br />
<br />
The main challenge at the moment is to achieve decent performance.<br />
<br />
Interested:<br />
* Roman Cheplyaka<br />
<br />
<br />
=== Kind-polymorphic Typeable ===<br />
<br />
Implement [http://hackage.haskell.org/trac/ghc/wiki/GhcKinds/PolyTypeable the new kind-polymorphic Typeable] in GHC.<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=45175DHD UHac/Projects2012-04-06T09:55:53Z<p>Dreixel: </p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Write a description of other GP libs in [http://www.haskell.org/haskellwiki/Generics the Haskell wiki]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5939 #5939]<br />
* Think about [http://hackage.haskell.org/trac/ghc/ticket/5936 #5936]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
=== Standard algorithms ===<br />
<br />
Objective point of this project is to implement or improve<br />
some standard algorithms like suffix arrays, z-function,<br />
cartesian trees, dijkstra algorithms which lack in standard library.<br />
<br />
Interested:<br />
* Victor Denisov<br />
<br />
Links:<br />
* https://github.com/haskellization/algorithms/wiki<br />
<br />
<br />
=== regex-applicative ===<br />
<br />
To learn about the project, see [https://github.com/feuerbach/regex-applicative/blob/master/README.md the README]. There will also be [http://www.haskell.org/haskellwiki/DHD_UHac/DHD_Program#regex-applicative a short talk] about it on the first day.<br />
<br />
The main challenge at the moment is to achieve decent performance.<br />
<br />
Interested:<br />
* Roman Cheplyaka<br />
<br />
<br />
=== Project Name ===<br />
<br />
Implement [http://hackage.haskell.org/trac/ghc/wiki/GhcKinds/PolyTypeable the new kind-polymorphic Typeable] in GHC.<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac&diff=45032DHD UHac2012-03-29T08:42:53Z<p>Dreixel: /* Introduction */ Make the language remark a bit more friendly, imho</p>
<hr />
<div>The [http://dutchhug.nl/ Dutch Haskell Users Group] is hosting a combined event for Haskell enthusiasts: an informal mini-conference and a weekend hackathon. It is the '''Dutch HUG Day''' followed by '''Utrecht Hackathon''', or more concisely ...<br />
<br />
<br/><br />
----<br />
<br />
{|<br />
| Event:<br />
| '''DHD >>= UHac'''<br />
|-<br />
| Dates:<br />
| '''April 20 - 22, 2012'''<br />
|-<br />
| Location:<br />
| '''Utrecht, The Netherlands'''<br />
|}<br />
<br />
----<br />
<br/><br />
<br />
Quick links:<br />
* [[DHD_UHac/Register|Register]] before '''April 1, 2012'''<br />
* [[DHD_UHac/Local|Local Information]]<br />
* [[DHD_UHac/DHD_Program|DHD Program]]<br />
* [[DHD_UHac/Projects|UHac Project Information]]<br />
<br />
----<br />
<br />
== Introduction ==<br />
<br />
The DHD and UHac are two events held over a long weekend and organized by the Dutch HUG.<br />
<br />
'''NOTE:''' Everything regarding the DHD >>= UHac is in English!<br />
<br />
=== Dutch HUG Day ===<br />
<br />
[[Image:Dhug2.png|35px]] The DHD will be on Friday, April 20. We invite people from all backgrounds to speak about their hobby projects, their research, or anything else related to functional programming.<br />
<br />
This will be the second time the Dutch HUG has hosted such an event. The [http://dutchhug.nl/dutchhugday first Dutch HUG Day] was held on April 24, 2010. It was a great success and brought together people from all over the Netherlands, as well as Germany and Belgium.<br />
<br />
We intend to make this year's DHD just as successful and open it to an even wider audience by binding it to a hackathon, which usually attracts people from all over Europe.<br />
<br />
=== Utrecht Hackathon ===<br />
<br />
[[Image:Hac-axe-icon.png|35px]] UHac immediately follows the DHD and lasts from Friday, April 20, to Sunday, April 22. In the now-grand tradition of [[Hackathon|Haskell hackathons]], UHac is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure.<br />
<br />
Haskell hackathons have been held every year since at least 2006. Utrecht hosted its first hackathon, [[Hac5]], in 2009, and this is the second.<br />
<br />
=== Dutch Haskell Users Group ===<br />
<br />
The Dutch HUG is an informal group with monthly meetings. Each meeting often includes talks on novel applications of functional programming. Other times, members just gather for drinks at a pub. The group was founded on April 19, 2009, at the end of [[Hac5]]. In April, 2012, the group celebrates its 3rd year of existence.<br />
<br />
== Call for speakers ==<br />
<br />
We are looking for speakers for the Dutch HUG Day. The topic can cover anything in the functional programming or Haskell world. It may be your latest pet project, current research, or simply a demonstration of something novel that you discovered. We are flexible about the time: it can be a lightning talk of 5 minutes, a full talk of 20 minutes, or even a longer hands-on tutorial.<br />
<br />
If you would like to give a talk, please send a title and abstract to Sean Leather ([mailto:leather@cs.uu.nl leather@cs.uu.nl]).<br />
<br />
== Schedule ==<br />
<br />
We have combined two events in the hopes that people interested in one might also take the opportunity to check out the other. Thus, it's much easier if the events are juxtaposed. In that light, here is a preliminary schedule to help you plan your time here.<br />
<br />
----<br />
{|<br />
! Date<br />
! Time<br />
! Event<br />
|-<br />
| Friday, April 20<br />
| 9:30 - 15:30<br />
| DHD at Ordina ([[DHD_UHac/Local#DHD_at_Ordina|venue]], [[DHD_UHac/DHD_Program|program]])<br />
|-<br />
|<br />
| 16:00 - 20:00<br />
| UHac at Newton ([[DHD_UHac/Local#UHac_at_Newton|venue]])<br />
|-<br />
| Saturday, April 21<br />
| 9:00 - 19:00<br />
| UHac at Newton ([[DHD_UHac/Local#UHac_at_Newton|venue]])<br />
|-<br />
| Sunday, April 22<br />
| 9:00 - 19:00<br />
| UHac at Newton ([[DHD_UHac/Local#UHac_at_Newton|venue]])<br />
|}<br />
----<br />
<br />
== Registration and Attendees ==<br />
<br />
Registration allows us (the organizers) to determine the number of participants (for logistics such as seating, lunch at the DHD, and rooms for UHac) and gives us a means to contact them. Please [[DHD_UHac/Register|register]]:<br />
<br />
{|<br />
| Registration Deadline:<br />
| '''April 1, 2012'''<br />
|}<br />
<br />
In addition to registering, it is often helpful to arrange things (such as accommodation, transportation, etc.) with other participants. Please include some information about yourself in the [[DHD_UHac/Attendees|list of attendees]], so that others may contact you to coordinate.<br />
<br />
== Project information ==<br />
<br />
Have plans for a project to work on during UHac? Want to find out about other people's projects? Check out the [[DHD_UHac/Projects|project page]] for details.<br />
<br />
== Local arrangements ==<br />
<br />
Refer to the [[DHD_UHac/Local|local information page]] for the latest on everything related to the location.<br />
<br />
== Discussion and Social ==<br />
<br />
;Email<br />
<br />
Use the [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org] mailing list to communicate broadly with other hackathon attendees.<br />
<br />
Join the [https://groups.google.com/group/dutch-hug dutch-hug@googlegroups.com] mailing list to chat with other Haskell hackers in the area of the Netherlands (and even occasionally Belgium and Germany). The Dutch Haskell Users Group meetings are announced on this list. Most communication is in English, since there are a number of foreigners involved.<br />
<br />
<!--<br />
;IRC<br />
<br />
#dhduhac<br />
--><br />
<br />
;Hash Tags<br />
<br />
On Twitter or Google+, use <code>#dhduhac</code> for all things related to DHD >>= UHac.<br />
<br />
* [https://twitter.com/#!/search/realtime/%23dhduhac Search Twitter]<br />
* [https://plus.google.com/s/%23dhduhac Search Google+]<br />
<br />
== Sponsors ==<br />
<br />
[[Image:OrdinaLogo.gif]]<br />
<br />
We are extremely grateful to [http://www.ordina.com/ Ordina] for hosting the Dutch HUG Day on their premises and for providing lunch to the participants. This is the second time they have hosted the DHD.<br />
<br />
Please check out their website:<br />
{|<br />
| English:<br />
| http://www.ordina.com/<br />
|-<br />
| Dutch:<br />
| http://www.ordina.nl/<br />
|}<br />
<br />
== Organizers ==<br />
<br />
The organizers are:<br />
<br />
* Sean Leather ([mailto:leather@cs.uu.nl leather@cs.uu.nl])<br />
* Jurri&euml;n Stutterheim ([mailto:j.stutterheim@uu.nl j.stutterheim@uu.nl])<br />
* Jurriaan Hage<br />
<br />
If you have any questions regarding the event, please feel free to contact us.<br />
<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=44963DHD UHac/Projects2012-03-20T07:45:53Z<p>Dreixel: /* GHC Generics */</p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Write a description of other GP libs in [http://www.haskell.org/haskellwiki/Generics the Haskell wiki]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5939 #5939]<br />
* Think about [http://hackage.haskell.org/trac/ghc/ticket/5936 #5936]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=44910DHD UHac/Projects2012-03-14T14:20:42Z<p>Dreixel: </p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5939 #5939]<br />
* Think about [http://hackage.haskell.org/trac/ghc/ticket/5936 #5936]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=44866DHD UHac/Projects2012-03-13T13:53:35Z<p>Dreixel: </p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Local&diff=44854DHD UHac/Local2012-03-13T09:00:26Z<p>Dreixel: </p>
<hr />
<div>This page should contain all the information you need to know to get to Utrecht, get around, and get out. If it doesn't, let us know.<br />
<br />
== Before you arrive! ==<br />
<br />
=== What to bring ===<br />
* A laptop with support for wireless networking. Ethernet access will probably not be available. If you really need ethernet access, please contact the organisers.<br />
* Power adapters if necessary. Power sockets in the Netherlands are 220-240V CEE 7/4 (a.k.a. "[http://en.wikipedia.org/wiki/Schuko Schuko]").<br />
* Mobile phone<br />
* A debit card, credit card and/or enough cash to sleep/eat/drink. Credit cards are generally not accepted in Dutch stores (and even restaurants), so be prepared to pay in some other way.<br />
<br />
=== Before you arrive ===<br />
* Pick out a couple of projects to work on and familiarise yourself with them<br />
* Install an up to date Haskell toolchain<br />
<br />
== Maps ==<br />
<br />
; Google Map<br />
<br />
Use '''[http://maps.google.com/maps/ms?msid=211877270309020342121.0004b89c16976b3a082db&msa=0 this map]''' to familiarize yourself with the locations relevant to the event. This includes the venues as well as accommodations and important transportation spots.<br />
<br />
If you can access Google Maps on your mobile phone, you can even view it there. If you need it, the short URL is http://g.co/maps/b6as8.<br />
<br />
; Map of the Uithof<br />
<br />
[http://plattegrond.uu.nl/print/uithofprintversie2008.pdf This PDF map] shows the Uithof campus of Utrecht University.<br />
<br />
; Map of University College Utrecht<br />
<br />
[http://www.uu.nl/university/college/EN/contactvisiting/PublishingImages/internationalcampusutrecht.jpg This JPEG map] shows the UCU campus.<br />
<br />
== Venues ==<br />
<br />
We are using several different venues for [[DHD_UHac|DHD >>= UHac]]. The main reason for this is money (or lack thereof).<br />
<br />
=== DHD at Ordina ===<br />
<br />
Ordina is gratefully sponsoring the DHD with their fine facilities and delicious food (Seriously! We held the first DHD there, and we're happy to go back.)<br />
<br />
==== Address ====<br />
<br />
[http://maps.google.com/maps?q=Ringwade+1,+3439LM+Nieuwegein,+The+Netherlands Ringwade 1, 3439LM Nieuwegein, The Netherlands]<br />
<br />
==== Getting there ====<br />
<br />
=== UHac at the BBL ===<br />
<br />
UHac starts out after the DHD in a classroom in the BBL (Buys Ballot Laboratorium) building at the "Uithof" (pronounced similar to "OUT-hof") campus of Utrecht University. Since the organizers are located there, and class is still in session, we don't have to pay a thing.<br />
<br />
==== Address ====<br />
<br />
[http://maps.google.com/maps?q=Princetonplein+5,+3584CC+Utrecht,+The+Netherlands Princetonplein 5, 3584CC Utrecht, The Netherlands]<br />
<br />
==== Getting there ====<br />
<br />
; By car<br />
<br />
Follow [http://www.uu.nl/EN/contactanddirections/deuithofbycar/Pages/default.aspx these directions] to reach the Uithof by car.<br />
<br />
; By bus<br />
<br />
From the central station, take bus 11 or 12. The both go to the Uithof, but they take different routes: bus 11 goes through the city center, and bus 12 stays to the south of the center.<br />
<br />
* With bus 11, take the "Botanische Tuinen" (Botanical Gardens) stop. The stop before is "Wim Sonneveldlaan."<br />
* With bus 12, take the "Padualaan" stop. The stop before is "Rijnsweerd Zuid."<br />
<br />
Once off the bus, walk north (from both stops) to the red building called the "Minnaert" (with its name spelled out in large letters on the facade).<br />
<br />
; Through the Minnaert<br />
<br />
[[Image:Minnaert.jpg|This is the Minnaert building, which is easier to spot. The arrow points to the BBL, immediately behind the Minnaert.]]<br />
<br />
Walk through the Minnaert to the BBL (indicated by the arrow in the photo above). The easiest way to find the path is by following a line of small, circular, metal plates on the walkway to the entrance of the Minnaert. These plates continue inside and lead directly to the BBL. Once you cross a bridge (with a view of bamboo!) into the BBL, simply take the stairs or elevator in the center of the building down to the ground floor and walk to the room.<br />
<br />
=== UHac at Newton ===<br />
<br />
Over the weekend, UHac will be held in classrooms at the University College Utrecht campus. UU wanted us to pay more than we could afford to keep the classroom (and thus the building) open when class was not in session, but UCU has students living on campus, so the buildings are already open, and we can afford their rates.<br />
<br />
==== Address ====<br />
<br />
[http://maps.google.com/maps?q=Campusplein+13-14,+3584ED,+Utrecht,+The+Netherlands Campusplein 13-14, 3584ED Utrecht, The Netherlands]<br />
<br />
==== Getting there ====<br />
<br />
; By car<br />
<br />
Follow [http://www.uu.nl/university/college/EN/contactvisiting/Pages/Directions.aspx these directions] to reach UCU by car.<br />
<br />
; By bus<br />
<br />
From the central station, take bus 12 in the direction of "Uithof UMC AZU." Get off at the stop "De Kromme Rijn." The stop before is "Stadion Galgenwaard."<br />
<br />
; From the bus stop<br />
<br />
Walk north/northwest (crossing the street from the bus stop) down Platolaan. The street makes a natural curve to the left and becomes Sophocleslaan and then curves right and becomes Prins Hendriklaan. There you will find the entrance to the UCU campus on your left.<br />
<br />
Walk through the pedestrian gate (and watch for cyclists going in and out). Take the left path walking around the central square. Newton Hall is the first building on the left at the corner of the square.<br />
<br />
== Accommodation ==<br />
<br />
See the map in section 2 for accommodation suggestions.<br />
<br />
== Transportation ==<br />
<br />
=== Getting to Utrecht ===<br />
<br />
Getting a train is the best (and cheapest) way of getting to Utrecht. Utrecht Central Station is where you need to get off. There are direct connections to Utrecht Central Station from Schiphol Airport and Eindhoven. People arriving at Eindhoven Airport will first need to take a bus to Eindhoven Central Station.<br />
<br />
=== Getting around Utrecht ===<br />
<br />
As mentioned before, getting to and from Newton is easy with bus 12. If you want a true Dutch commuting experience, however, consider [http://www.laagcatharijne.nl/verhuur.html renting a bicycle (Dutch)]. It's the easiest way to get to Newton and to the city centre.<br />
<br />
== Restaurants ==<br />
<br />
=== Italian ===<br />
* [http://maps.google.nl/maps?q=il+pozzo&hl=nl&fb=1&gl=nl&hq=il+pozzo&hnear=0x47c66f4339d32d37:0xd6c8fc4c19af4ae9,Utrecht&cid=0,0,111793244555536424&t=m&z=16&iwloc=A Il Pozzo]<br />
* [http://www.ristorantelafontana.nl/ La Fontana]<br />
* [http://www.pizzeriatricolore.nl/ Tricolore]<br />
<br />
=== Vegetarian ===<br />
* [http://www.dewerfkring.com/?lang=en De Werfkring]<br />
<br />
=== Pancakes ===<br />
* [http://www.theehuisrhijnauwen.nl/theehuis/home.html Theehuis Rhijnauwen]<br />
* [http://www.deoudemuntkelder.nl/ De Oude Muntkelder]</div>Dreixelhttps://wiki.haskell.org/index.php?title=Talk:GHC.Generics&diff=44728Talk:GHC.Generics2012-03-03T17:39:59Z<p>Dreixel: </p>
<hr />
<div>Why does the definition of (:+:) use the pipe character "|", but the definition of (:*:) uses the ":*:" operator?<br />
<br />
<br />
Is that a typo (copied from http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/generic-programming.html), or is there a reason for the difference?<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
<br />
<br />
Is it just fallout from of "asymmetry" in Haskell language spec, <br />
where Sum types need the pipe to separate the alternations, <br />
but Product types are written with the factors simply adjacent without a separator? (and then it looks pretty to use infix constructor "+351916292294" instead of a prefix constructor "P")<br />
<br />
----<br />
<br />
Yes, the pipe separates different constructors of a datatype, and the (:*:) is an infix constructor.<br />
<br />
--[[User:Dreixel|dreixel]] 17:39, 3 March 2012 (UTC)</div>Dreixelhttps://wiki.haskell.org/index.php?title=DHD_UHac/Attendees&diff=44517DHD UHac/Attendees2012-02-13T19:50:16Z<p>Dreixel: </p>
<hr />
<div>This is a list of attendees for [[DHD_UHac|DHD >>= UHac]].<br />
<br />
If you have [[DHD_UHac/Register|registered]], please consider adding yourself to the list. Your contact and travel information may help with coordination between participants.<br />
<br />
If you live around Utrecht or plan to commute from home each day, you may put "Local" for accommodation.<br />
<br />
{| class="wikitable"<br />
! Nickname<br />
! Real Name (Affl)<br />
! Mobile #<br />
! Arrive<br />
! Depart<br />
! Accommodation<br />
|-<br />
| leather<br />
| Sean Leather (UU)<br />
| +31616158163<br />
|<br />
|<br />
| Local<br />
|-<br />
| ruud<br />
| Ruud Koot (UU)<br />
| +31623024223<br />
|<br />
|<br />
| Local<br />
|-<br />
| kosmikus<br />
| Andres Löh (Well-Typed LLP)<br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| sol<br />
| Simon Hengel<br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| dreixel<br />
| José Pedro Magalhães (UU)<br />
| +31650459029<br />
|<br />
|<br />
| Local<br />
|}</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=43607GHC/Kinds2011-12-13T13:18:47Z<p>Dreixel: /* Which data types are promotable? */ update link to paper</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
Simply [http://hackage.haskell.org/trac/ghc/wiki/Building build GHC HEAD].<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://dreixel.net/research/pdf/ghp.pdf this paper].<br />
<br />
A simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=43260GHC/Kinds2011-11-28T16:28:43Z<p>Dreixel: Remove the branch story</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
Simply [http://hackage.haskell.org/trac/ghc/wiki/Building build GHC HEAD].<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://research.microsoft.com/en-us/people/dimitris/fc-kind-poly.pdf this paper].<br />
<br />
A simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=42853GHC/Kinds2011-11-11T10:54:10Z<p>Dreixel: /* Which data types are promotable? */</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
You first need to [http://hackage.haskell.org/trac/ghc/wiki/Building get the sources] and checkout the branch:<br />
<br />
$ git clone http://darcs.haskell.org/ghc.git ghc-kinds<br />
$ cd ghc-kinds<br />
$ ./sync-all --testsuite get<br />
$ ./sync-all checkout ghc-kinds<br />
<br />
Make sure you are up-to-date:<br />
<br />
$ ./sync-all pull<br />
<br />
You can now build the compiler:<br />
$ perl boot<br />
$ ./configure<br />
$ make<br />
Or run the testsuite:<br />
$ sh validate<br />
<br />
In both cases the resulting compiler will be located at <code>inplace/bin/ghc-stage2</code>.<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://research.microsoft.com/en-us/people/dimitris/fc-kind-poly.pdf this paper].<br />
<br />
A simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=42852GHC/Kinds2011-11-11T10:53:56Z<p>Dreixel: /* Which data types are promotable? */</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
You first need to [http://hackage.haskell.org/trac/ghc/wiki/Building get the sources] and checkout the branch:<br />
<br />
$ git clone http://darcs.haskell.org/ghc.git ghc-kinds<br />
$ cd ghc-kinds<br />
$ ./sync-all --testsuite get<br />
$ ./sync-all checkout ghc-kinds<br />
<br />
Make sure you are up-to-date:<br />
<br />
$ ./sync-all pull<br />
<br />
You can now build the compiler:<br />
$ perl boot<br />
$ ./configure<br />
$ make<br />
Or run the testsuite:<br />
$ sh validate<br />
<br />
In both cases the resulting compiler will be located at <code>inplace/bin/ghc-stage2</code>.<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://research.microsoft.com/en-us/people/dimitris/fc-kind-poly.pdf this paper].<br />
<br />
An simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=42745GHC/Kinds2011-11-04T08:00:57Z<p>Dreixel: /* How do I use it? */</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
You first need to [http://hackage.haskell.org/trac/ghc/wiki/Building get the sources] and checkout the branch:<br />
<br />
$ git clone http://darcs.haskell.org/ghc.git ghc-kinds<br />
$ cd ghc-kinds<br />
$ ./sync-all --testsuite get<br />
$ ./sync-all checkout ghc-kinds<br />
<br />
Make sure you are up-to-date:<br />
<br />
$ ./sync-all pull<br />
<br />
You can now build the compiler:<br />
$ perl boot<br />
$ ./configure<br />
$ make<br />
Or run the testsuite:<br />
$ sh validate<br />
<br />
In both cases the resulting compiler will be located at <code>inplace/bin/ghc-stage2</code>.<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://gallium.inria.fr/~jcretin/ghc/theory.pdf the theory paper].<br />
<br />
An simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC/Kinds&diff=42744GHC/Kinds2011-11-04T08:00:09Z<p>Dreixel: /* How do I use it? */</p>
<hr />
<div>Kinds (this is not the definitive name) will be a language extension adding a kind level and some kind polymorphic support to Haskell.<br />
<br />
== What does this extension do? ==<br />
<br />
Haskell defines [[Kind|kinds]] as <code>&kappa; ::= * | &kappa; -> &kappa;</code>. Nowadays, programmers use type-level computation more often using [[GADT|GADTs]] and [[GHC/Type families|type families]]. The need of a well-kinded type-level computation has become bigger. This extension provides a simple mechanism called ''promotion'' to populate the kind level.<br />
<br />
Each time the user defines a ''promotable'' data type at the term level, he will be able to use it at the type level too. For instance, the user can write the following example:<br />
<br />
<haskell><br />
data Nat = Zero | Succ Nat<br />
data Vector :: * -> Nat -> * where<br />
VNil :: Vector a Zero<br />
VCons :: a -> Vector a n -> Vector a (Succ n)<br />
<br />
data List a = Nil | Cons a (List a)<br />
data HList :: List * -> * where<br />
HNil :: HList Nil<br />
HCons :: a -> HList as -> HList (Cons a as)<br />
</haskell><br />
<br />
== How do I use it? ==<br />
<br />
You first need to [http://hackage.haskell.org/trac/ghc/wiki/Building get the sources] and checkout the branch:<br />
<br />
$ git clone http://darcs.haskell.org/ghc.git ghc-kinds<br />
$ cd ghc-kinds<br />
$ ./sync-all --testsuite get<br />
$ ./sync-all checkout ghc-kinds<br />
<br />
You can now build the compiler:<br />
$ perl boot<br />
$ ./configure<br />
$ make<br />
Or run the testsuite:<br />
$ sh validate<br />
<br />
In both cases the resulting compiler will be located at <code>inplace/bin/ghc-stage2</code>.<br />
<br />
== Which data types are promotable? ==<br />
<br />
A data type is promotable if its type constructor and data constructors are. A type constructor is promotable if it is of the form <hask>* -> .. * -> *</hask> which is a first-order Haskell98 type constructor. All Haskell98 data constructors of a first-order Haskell98 data type are promotable. More details can be found in [http://gallium.inria.fr/~jcretin/ghc/theory.pdf the theory paper].<br />
<br />
An simple way to decide if your data type is promotable is to see if you can write without the where-clause like this:<br />
<haskell><br />
data T (a::*) (b::*) (c::*) = A a | B Int b | C (Either a c) [b]<br />
</haskell></div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=42715GHC.Generics2011-11-03T08:38:41Z<p>Dreixel: /* A generic function */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=42687GHC.Generics2011-11-01T09:38:17Z<p>Dreixel: Fixes from old syntax</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Generic</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Generic</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Generic<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveGeneric</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Generic a, GSerialize (Rep a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
put a = gput (from a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Generic</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=HaskellImplementorsWorkshop/2011&diff=42146HaskellImplementorsWorkshop/20112011-09-21T03:22:55Z<p>Dreixel: Remove a name that was part of talk title</p>
<hr />
<div>The Haskell Implementors Workshop is an informal affair, aimed at bringing together people behind the Haskell infrastructure. It provides a forum where people working on compilers, tools, or libraries for Haskell development can bat around ideas, share experiences and ask for feedback from fellow experts. There are no proceedings, just a mixture of short talks, longer talks, discussion and demos.<br />
<br />
The Haskell Implementors Workshop will run again this year, co-located with [http://www.icfpconference.org/icfp2011/ ICFP 2011]. <br />
<br />
== Links ==<br />
<br />
* [[HaskellImplementorsWorkshop/2011/Call_for_Talks|Call for Talks]]<br />
<br />
== Important Dates ==<br />
<br />
* '''Friday 22nd July''': Proposal Deadline<br />
* '''Monday 8th August''': Notification<br />
* '''Friday 23rd September''': Workshop<br />
<br />
== Programme ==<br />
<br />
9:00-10:00 Session 1<br />
* '''[[HaskellImplementorsWorkshop/2011/Heijer|Improving the GHC Inliner: Smart Loop Breaker Choice]]''' (Bas den Heijer)<br />
* '''[[HaskellImplementorsWorkshop/2011/Tibell|Faster persistent data structures through hashing]]''' (Johan Tibell)<br />
<br />
10:00-10:30: Tea Break<br />
<br />
10:30-12:00: Session 2<br />
* '''[[HaskellImplementorsWorkshop/2011/Coutts|Spark Visualization in ThreadScope]]''' (Duncan Coutts)<br />
* '''[[HaskellImplementorsWorkshop/2011/Wortmann|Weaving Source Code into ThreadScope]]''' (Peter Wortmann)<br />
* First Lightning Talks Session<br />
<br />
12:00-13:30: Lunch Break<br />
<br />
13:30-15:00: Session 3<br />
* '''GHC Status Update''' (Simon Peyton Jones and Simon Marlow)<br />
* '''[[HaskellImplementorsWorkshop/2011/Takano|Reusing Thunks for Recursive Data Structures in Lazy Functional Programs]]''' (Yasunao TAKANO)<br />
* Second Lightning Talks Session<br />
<br />
15:00-15:30: Tea Break<br />
<br />
15:30-16:30 Session 4 <br />
* '''[[HaskellImplementorsWorkshop/2011/WinogradCort|Virtualizing Real-World Objects in Functional Reactive Programming]]''' (Daniel Winograd-Cort)<br />
* '''[[HaskellImplementorsWorkshop/2011/Loeh|A New Dependency Solver for cabal-install]]''' (Andres Löh)<br />
<br />
16:30-16:45: Short Break<br />
<br />
16:45-17:45: Session 5<br />
* '''[[HaskellImplementorsWorkshop/2011/Terei|Safe Haskell]]''' (David Terei)<br />
* Third Lightning Talks Session and Beyond Haskell Discussion<br />
<br />
== Organisers ==<br />
<br />
* [http://web.cecs.pdx.edu/~rebekah/ Rebekah Leslie] (Portland State University)<br />
* [http://www.cse.unsw.edu.au/~benl/ Ben Lippmeier] - co-chair (University of New South Wales)<br />
* [http://people.cs.uu.nl/andres/ Andres Löh] (Well-Typed LLP)<br />
* [http://www.mathematik.uni-marburg.de/~lobachev Oleg Lobachev] (University of Marburg)<br />
* [http://neilmitchell.blogspot.com/ Neil Mitchell] - co-chair (Standard Chartered)<br />
* [http://research.microsoft.com/en-us/people/dimitris/ Dimitrios Vytiniotis] (Microsoft Research)</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=40522GHC.Generics2011-06-16T06:13:08Z<p>Dreixel: Correct mistake</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=40102GHC.Generics2011-05-25T07:53:17Z<p>Dreixel: </p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We show how this all works in this page, starting with a detailed example.<br />
<br />
Since this is a fresh new feature, it is possible that you will run into bugs when using it. If so, please<br />
[http://hackage.haskell.org/trac/ghc/wiki/ReportABug report them]!<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=User:Dreixel&diff=39903User:Dreixel2011-05-11T09:09:27Z<p>Dreixel: </p>
<hr />
<div>[http://www.dreixel.net dreixel.net]</div>Dreixelhttps://wiki.haskell.org/index.php?title=User:Dreixel&diff=39902User:Dreixel2011-05-11T09:09:15Z<p>Dreixel: New page: [http://www.dreixel.net]</p>
<hr />
<div>[http://www.dreixel.net]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39901GHC.Generics2011-05-11T09:08:37Z<p>Dreixel: /* Changes from the paper */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in the "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39900GHC.Generics2011-05-11T09:07:56Z<p>Dreixel: /* Limitations */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot be easily expressed generically in GHC yet.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39899GHC.Generics2011-05-11T09:07:25Z<p>Dreixel: /* Changes from the paper */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the <tt>Encode</tt> class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot yet be easily expressed generically in GHC.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39898GHC.Generics2011-05-11T09:07:06Z<p>Dreixel: /* Changes from the paper */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a <tt>DERIVABLE</tt> pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the `Encode` class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot yet be easily expressed generically in GHC.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39897GHC.Generics2011-05-11T09:06:48Z<p>Dreixel: /* Changes from the paper */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a `DERIVABLE` pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the `Encode` class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses <hask>deriving instance</hask> (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot yet be easily expressed generically in GHC.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.<br />
<br />
<br />
[[Category:GHC]]<br />
[[Category:Language extensions]]</div>Dreixelhttps://wiki.haskell.org/index.php?title=GHC.Generics&diff=39847GHC.Generics2011-05-09T08:36:14Z<p>Dreixel: /* Default implementations */</p>
<hr />
<div>GHC 7.2 includes support for ''datatype-generic programming''. This means you can have more classes for which you do not have to give an instance, like <hask>Show</hask> or <hask>Functor</hask>. This is accomplished through two new features, enabled with two new flags: <tt>DeriveGeneric</tt> and <tt>DefaultSignatures</tt>. We'll show how this all works in this page, starting with a detailed example.<br />
<br />
== Example: serialization ==<br />
<br />
Suppose you are writing a class for serialization of data. You have a type <hask>Bit</hask> representing bits, and a class <hask>Serialize</hask>:<br />
<br />
<haskell><br />
data Bit = O | I<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
</haskell><br />
<br />
You might have written some instances already:<br />
<br />
<haskell><br />
instance Serialize Int where<br />
put i = serializeInt i<br />
<br />
instance Serialize a => Serialize [a] where<br />
put [] = []<br />
put (h:t) = put h ++ put t<br />
</haskell><br />
<br />
A user of your library, however, will have his own datatypes, like:<br />
<br />
<haskell><br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
</haskell><br />
<br />
He will have to specify an <hask>instance Serialize (UserTree a) where ...</hask> himself. This, however, is tedious, especially because most instances will probably be rather trivial, and should be derived automatically.<br />
<br />
It is here that generic programming can help you. If you are familiar with [http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/SYB SYB] you could use it at this stage, but now we'll see how to do this with the new features of GHC 7.2.<br />
<br />
=== Generic serialization ===<br />
<br />
First you have to tell the compiler how to serialize any datatype, in general. Since Haskell datatypes have a regular structure, this means you can just explain how to serialize a few basic datatypes.<br />
<br />
==== Representation types ====<br />
<br />
We can represent most Haskell datatypes using only the following primitive types:<br />
<br />
<haskell><br />
-- | Unit: used for constructors without arguments<br />
data U1 p = U1<br />
<br />
-- | Constants, additional parameters and recursion of kind *<br />
newtype K1 i c p = K1 { unK1 :: c }<br />
<br />
-- | Meta-information (constructor names, etc.)<br />
newtype M1 i c f p = M1 { unM1 :: f p }<br />
<br />
-- | Sums: encode choice between constructors<br />
infixr 5 :+:<br />
data (:+:) f g p = L1 (f p) | R1 (g p)<br />
<br />
-- | Products: encode multiple arguments to constructors<br />
infixr 6 :*:<br />
data (:*:) f g p = f p :*: g p<br />
</haskell><br />
<br />
For starters, try to ignore the <tt>p</tt> parameter in all types; it's there just for future compatibility. The easiest way to understand how you can use these types to represent others is to see an example. Let's represent the <hask>UserTree</hask> type shown before:<br />
<br />
<haskell><br />
type RepUserTree a =<br />
-- A UserTree is either a Leaf, which has no arguments<br />
U1<br />
-- ... or it is a Node, which has three arguments that we put in a product<br />
:+: a :*: UserTree a :*: UserTree a<br />
</haskell><br />
<br />
Simple, right? Different constructors become alternatives of a sum, and multiple arguments become products. In fact, we want to have some more information in the representation, like datatype and constructor names, and to know if a product argument is a parameter or a type. We use the other primitives for this, and the representation looks more like:<br />
<br />
<haskell><br />
type RealRepUserTree a =<br />
-- Information about the datatype<br />
M1 D Data_UserTree (<br />
-- Leaf, with information about the constructor<br />
M1 C Con_Leaf U1<br />
-- Node, with information about the constructor<br />
:+: M1 C Con_Node (<br />
-- Constructor argument, which could have information<br />
-- about a record selector label<br />
M1 S NoSelector (<br />
-- Argument, tagged with P because it is a parameter<br />
K1 P a)<br />
-- Another argument, tagged with R because it is <br />
-- a recursive occurrence of a type<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
-- Idem<br />
:*: M1 S NoSelector (K1 R (UserTree a))<br />
))<br />
</haskell><br />
<br />
A bit more complicated, but essentially the same. Datatypes like <hask>Data_UserTree</hask> are empty datatypes used only for providing meta-information in the representation; you don't have to worry much about them for now. Also, GHC generates these representations for you automatically, so you should never have to define them yourself! All of this is explained in much more detail in Section 2.1. of [http://dreixel.net/research/pdf/gdmh.pdf the original paper describing the new generic deriving mechanism].<br />
<br />
==== A generic function ====<br />
<br />
Since GHC can represent user types using only those primitive types, all you have to do is to tell GHC how to serialize each of the individual primitive types. The best way to do that is to create a new type class:<br />
<br />
<haskell><br />
class GSerialize f where<br />
gput :: f a -> [Bin]<br />
</haskell><br />
<br />
This class looks very much like the original <hask>Serialize</hask> class, just that the type argument is of kind <hask>* -> *</hask>, since our generic representation types have this <tt>p</tt> parameter lying around. Now we need to give instances for each of the basic types. For units there's nothing to serialize:<br />
<br />
<haskell><br />
instance GSerialize U1 where<br />
gput U1 = []<br />
</haskell><br />
<br />
The serialization of multiple arguments is simply the concatenation of each of the individual serializations:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where<br />
gput (a :*: b) = gput a ++ gput b<br />
</haskell><br />
<br />
The case for sums is the most interesting, as we have to record which alternative we are in. We will use a 0 for left injections and a 1 for right injections:<br />
<br />
<haskell><br />
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where<br />
gput (L1 x) = O : gput x<br />
gput (R1 x) = I : gput x<br />
</haskell><br />
<br />
We don't need to encode the meta-information, so we just go over it recursively :<br />
<br />
<haskell><br />
instance (GSerialize a) => GSerialize (M1 i c a) where<br />
gput (M1 x) = gput x<br />
</haskell><br />
<br />
Finally, we're only left with the arguments. For these we will just use our first class, <hask>Serialize</hask>, again:<br />
<br />
<haskell><br />
instance (Serialize a) => GSerialize (K1 i c a) where<br />
gput (K1 x) = put x<br />
</haskell><br />
<br />
So, if a user datatype has a parameter which is instantiated to <hask>Int</hask>, at this stage we will use the library instance for <hask>Serialize Int</hask>.<br />
<br />
==== Default implementations ====<br />
<br />
We've seen how to represent user types generically, and how to define functions on representation types. However, we still have to tie these two together, explaining how to convert user types to their representation and then applying the generic function.<br />
<br />
The representation <hask>RepUserTree</hask> we have seen earlier is only one component of the representation; we also need functions to convert to and from the user datatype into the representation. For that we use another type class:<br />
<br />
<haskell><br />
class Generic a where<br />
-- Encode the representation of a user datatype<br />
type Rep a :: * -> *<br />
-- Convert from the datatype to its representation<br />
from :: a -> (Rep a) x<br />
-- Convert from the representation to the datatype<br />
to :: (Rep a) x -> a<br />
</haskell><br />
<br />
So, for the <hask>UserTree</hask> datatype shown before, GHC generates the following instance:<br />
<br />
<haskell><br />
instance Generic (UserTree a) where<br />
type Rep (UserTree a) = RepUserTree a<br />
<br />
from Leaf = L1 U1<br />
from (Node a l r) = R1 (a :*: l :*: r)<br />
<br />
to (L1 U1) = Leaf<br />
to (R1 (a :*: l :*: r)) = Node a l r<br />
</haskell><br />
<br />
(Note that we are using the simpler representation <hask>RepUserTree</hask> instead of the real representation <hask>RealRepUserTree</hask>, just for simplicity.)<br />
<br />
Equipped with a <hask>Generic</hask> instance, we are ready to tell the compiler how it can serialize any representable type:<br />
<br />
<haskell><br />
putDefault :: (Generic a, GSerialize (Rep a)) => a -> [Bit]<br />
putDefault a = gput (from a)<br />
</haskell><br />
<br />
The type of <hask>putDefault</hask> says that we can serialize any <tt>a</tt> into a list of bits, as long as that <tt>a</tt> is <hask>Generic</hask>, and its representation <hask>Rep a</hask> has a <hask>GSerialize</hask> instance. The implementation is very simple: first convert the value to its representation using <hask>from</hask>, and then call <hask>gput</hask> on that representation.<br />
<br />
However, we still have to write a <hask>Serialize</hask> instance for the user dataype:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a) where<br />
put = putDefault<br />
</haskell><br />
<br />
=== Using GHC's new features ===<br />
<br />
What we have seen so far could all already be done, at the cost of writing a lot of boilerplate code yourself (or spending hours writing [[Template Haskell]] code to do it for you). Now we'll see how the new features of GHC can help you.<br />
<br />
==== Deriving representations ====<br />
<br />
The <hask>Representable0</hask> class, and all the representation types, come with GHC in the <tt>GHC.Generics</tt> module. GHC can also derive <hask>Representable0</hask> for user types, so all the user has to do is:<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveRepresentable #-}<br />
<br />
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf<br />
deriving Representable0<br />
</haskell><br />
<br />
(Standlone deriving also works fine, and you can use it for types you have not defined yourself, but are imported from somewhere else.) You will need the new <tt>DeriveRepresentable</tt> language pragma.<br />
<br />
==== More general default methods ====<br />
<br />
We don't want the user to have to write the <hask>instance Serialize (UserTree a)</hask> himself, since most of the times it will just be <hask>putDefault</hask>. However, we cannot make <hask>putDefault</hask> the default implementation of the <hask>put</hask> method, because that would require adding the <hask>(Representable0 a, GSerialize (Rep0 a))</hask> constraint to the class head. This would restrict the ability to give ad-hoc instances for types that are not representable, for instance.<br />
<br />
We solved this by allowing the user to give a different signature for default methods:<br />
<br />
<haskell><br />
{-# LANGUAGE DefaultSignatures #-}<br />
<br />
class Serialize a where<br />
put :: a -> [Bit]<br />
<br />
default put :: (Representable0 a, GSerialize (Rep0 a)) => a -> [Bit]<br />
put a = gput (from0 a)<br />
</haskell><br />
<br />
With the new language pragma <tt>DefaultSignatures</tt>, GHC allows you to put the keyword <hask>default</hask> before a (new) type signature for a method inside a class declaration. If you give such a default type signature, then you have to provide a default method implementation, which will be type-checked using the default signature, and not the original one.<br />
<br />
Now the user can simply write:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
GHC fills out the implementation for <hask>put</hask> using the default method. It will type-check correctly because we have a <hask>Representable0</hask> instance for <hask>UserTree</hask>, and <hask>GSerialize</hask> instances for all the representation types.<br />
<br />
== Different perspectives ==<br />
<br />
We outline the changes introduced in 7.2 regarding support for generic programming from the perspective of three different types of users: the end-user, the generic programmer, and the GHC hacker.<br />
<br />
=== The end-user ===<br />
<br />
If you know nothing about generic programming and would like to keep it that way, then you will be pleased to know that using generics in GHC 7.2 is easier than ever. As soon as you encounter a class with a default signature (like <tt>Serialize</tt> above), you will be able to give empty instances for your datatypes, like this:<br />
<br />
<haskell><br />
instance (Serialize a) => Serialize (UserTree a)<br />
</haskell><br />
<br />
You will need to add a <hask>deriving Generic</hask> clause to each datatype that you want to have generic implementations for. You might have datatypes that use other datatypes, and you might need <tt>Generic</tt> instances for those too. In that case, you can import the module where the datatype is defined and give a standalone deriving <tt>Generic</tt> instance. In either case, you will need the <tt>-XDeriveGeneric</tt> flag.<br />
<br />
=== The generic programmer ===<br />
<br />
If you are a library author and are eager to make your classes easy to instantiate by your users, then you should invest some time in defining instances for each of the representation types of <tt>GHC.Generics</tt> and defining a generic default method. See the example for <tt>Serialize</tt> above, and the [http://dreixel.net/research/pdf/gdmh.pdf original paper] for many other examples (but make sure to check the [[Generics#Changes from the paper|changes from the paper]]).<br />
<br />
=== The GHC hacker ===<br />
<br />
If you are working on the GHC source code, you might find it useful to know what kind of changes were made. There is a [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving Trac wiki page] with a lower-level overview of things and also keeping track of what still needs to be done.<br />
<br />
== Changes from the paper ==<br />
<br />
In the [http://dreixel.net/research/pdf/gdmh.pdf paper] we describe the implementation in [http://www.cs.uu.nl/wiki/UHC UHC]. The implementation in GHC is slightly different:<br />
<br />
* <tt>Representable0</tt> and <tt>Representable1</tt> have become <tt>Generic</tt> and <tt>Generic1</tt>, respectively. <tt>from0</tt>, <tt>to0</tt>, and <tt>Rep0</tt> also lost the <tt>0</tt> at the end of their names.<br />
<br />
* We are using type families, so the <tt>Generic</tt> and <tt>Generic1</tt> type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.<br />
<br />
* Default definitions (Section 3.3) work differently. In GHC we don't use a `DERIVABLE` pragma; instead, a type class can declare a ''generic default method'', which is akin to a standard default method, but includes a default type signature. This removes the need for a separate default definition and a pragma. For example, the `Encode` class of Section 3.1 is now:<br />
<haskell><br />
class Encode a where<br />
encode :: a -> [Bit]<br />
default encode :: (Generic a, Encode1 (Rep a)) => a -> [Bit]<br />
encode = encode1 . from<br />
</haskell><br />
<br />
* To derive generic functionality to a user type, the user no longer uses ``deriving instance`` (Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:<br />
<haskell><br />
instance Encode [a] -- works if there is an instance Generic [a]<br />
</haskell><br />
<br />
== Limitations ==<br />
<br />
* We do not yet allow <hask>deriving Generic1</hask> clauses. This means that functions like <tt>fmap</tt> cannot yet be easily expressed generically in GHC.<br />
<br />
* We cannot derive <tt>Generic</tt> instances for:<br />
** Datatypes with a context;<br />
** Existentially-quantified datatypes;<br />
** GADTs.</div>Dreixel