https://wiki.haskell.org/api.php?action=feedcontributions&user=Heisenbug&feedformat=atomHaskellWiki - User contributions [en]2020-07-10T07:46:25ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=Haskell_Quiz/FizzBuzz/Solution_Heisenbug&diff=62044Haskell Quiz/FizzBuzz/Solution Heisenbug2017-07-31T17:52:07Z<p>Heisenbug: use ++ from Prelude</p>
<hr />
<div> {-# LANGUAGE LambdaCase #-}<br />
<br />
main = mapM_ (putStrLn . fizzbuzz) [1 .. 100]<br />
where fizzbuzz n = (\case "" -> show n; fb -> fb)<br />
(concat $ ["fizz" | n `rem` 3 == 0] ++ ["buzz" | n `rem` 5 == 0])</div>Heisenbughttps://wiki.haskell.org/index.php?title=Haskell_Quiz/FizzBuzz/Solution_Heisenbug&diff=62043Haskell Quiz/FizzBuzz/Solution Heisenbug2017-07-31T17:49:37Z<p>Heisenbug: formatting</p>
<hr />
<div> {-# LANGUAGE LambdaCase #-}<br />
<br />
main = mapM_ (putStrLn . fizzbuzz) [1 .. 100]<br />
where fizzbuzz n = (\case "" -> show n; fb -> fb)<br />
(concat $ ["fizz" | n `rem` 3 == 0] <> ["buzz" | n `rem` 5 == 0])</div>Heisenbughttps://wiki.haskell.org/index.php?title=Haskell_Quiz/FizzBuzz/Solution_Heisenbug&diff=62042Haskell Quiz/FizzBuzz/Solution Heisenbug2017-07-31T17:48:31Z<p>Heisenbug: fun exercise</p>
<hr />
<div>{-# LANGUAGE LambdaCase #-}<br />
<br />
main = mapM_ (putStrLn . fizzbuzz) [1 .. 100]<br />
where fizzbuzz n = (\case "" -> show n; fb -> fb)<br />
(concat $ ["fizz" | n `rem` 3 == 0] <> ["buzz" | n `rem` 5 == 0])</div>Heisenbughttps://wiki.haskell.org/index.php?title=Haskell_Quiz/FizzBuzz&diff=62041Haskell Quiz/FizzBuzz2017-07-31T17:43:38Z<p>Heisenbug: add GGR</p>
<hr />
<div>"There has been some debate on the proper ways to screen programmers you intend to hire. A common theory is that you really need to have the programmer write some code for you to accurately gauge their skill. Exactly what to have them write is another debate, but the blogosphere has recently been abuzz with this question as a screener:<br />
<br />
Write a program that prints the numbers from 1 to 100.<br />
But for multiples of three print “Fizz” instead of the<br />
number and for the multiples of five print “Buzz”. For<br />
numbers which are multiples of both three and five<br />
print “FizzBuzz”.<br />
<br />
Pretend you've just walked into a job interview and been hit with this question. Solve it as you would under such circumstances for this week's Ruby Quiz."<br />
<br />
==The problem==<br />
<br />
* http://www.rubyquiz.com/quiz126.html<br />
<br />
==Solutions==<br />
<br />
* [[Haskell Quiz/FizzBuzz/Solution Ninju|Alex Watt]]<br />
* [[Haskell Quiz/FizzBuzz/Solution Syzygies|Dave Bayer]]<br />
* [[Haskell Quiz/FizzBuzz/Solution Mikbe|Mike Bethany]]<br />
* [[Haskell Quiz/FizzBuzz/Solution Acontorer|Aaron Contorer]]<br />
* [[Haskell Quiz/FizzBuzz/Solution Heisenbug|Gabor Greif]]<br />
<br />
[[Category:Haskell Quiz|FizzBuzz]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Budapest_Hackathon_2017&diff=62026Budapest Hackathon 20172017-07-28T04:14:07Z<p>Heisenbug: /* Local arrangements */</p>
<hr />
<div>[[File:Bp hh 2017.png|768px]]<br />
<br />
[[File:Budapest01.jpg|300px|right]]<br />
[[File:BudapestPub01.jpg|300px|right]]<br />
[[File:BudapestPub02.jpg|300px|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|2017July 29 - 30th (Saturday & Sunday)<br />
|-<br />
|Hours:<br />
|09:00 ~ 17:00<br />
|-<br />
|Where:<br />
|[https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media Hungary, 1062 Andrássy út 66.]<br />
|}<br />
----<br />
<br />
<br />
== About ==<br />
<br />
[https://meetup.com/Bp-HUG/ The Budapest Haskell User Group] will once again hold a two day Haskell Hackathon in Budapest. This is the third the occasion (info about [https://wiki.haskell.org/BudapestHackathon2014 the first], [https://wiki.haskell.org/Budapest_Hackathon_2016 and second hackathon]), and this time we will hold it in Gizmodo Media Group's Budapest office.<br />
The event is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure, and growing the local community.<br />
<br />
This is a great opportunity to meet your fellow Haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones!<br />
<br />
This event is open to any experience level, from beginners to gurus. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community. We will have a dedicated beginners' track, and there are going to be experienced haskellers on site whom you can directly approach during the whole event with any Haskell-related question that might pop up.<br />
<br />
There will be lots of hacking, good food, and, of course, fun!<br />
<br />
<p><br />
<br />
== Sponsors ==<br />
<br />
[[File:Gmg logo.png|center|200px]]<br />
[[File:Digital asset logo.png|center|400px]]<br />
[[File:Iseeq logo.png|center|250px]]<br />
<br />
Many thanks to [http://gizmodo.com/careers/budapest#openings GMG] for hosting, and [https://digitalasset.com Digital Asset], and [http://iseeq.co IseeQ] for sponsoring the event.<br />
<br />
== Registration ==<br />
<br />
You can fill out the necessary registration information [https://goo.gl/forms/QjTNdXTD1aEOMEQU2 here]. <br/>There is no registration deadline, or requirement really, so you can join us even if you didn't fill out the form, it just helps us with the organization.<br />
<br />
== Venue ==<br />
<br />
[[File:a66_front.jpg|300px|right]]<br />
[[File:a66_inside_1.jpg|300px|right]]<br />
[[File:a66_inside_2.jpg|300px|right]]<br />
<br />
The Hackathon will be held at [https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media's Budapest office]. WiFi, projectors for talks, and snacks & refreshments will be provided by our sponsors.<br/><br />
Detailed schedules will be posted soon.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Budapest ===<br />
You can find out more about [http://www.budapest.com/ Budapest] on [http://wikitravel.org/en/Budapest these] [https://www.tripadvisor.com/Tourism-g274887-Budapest_Central_Hungary-Vacations.html sites]. Travel informations can be found on [http://bud.hu/english bud.hu].<br />
<br />
==== By Plane ====<br />
<br />
From [https://www.google.com/maps/place/Budapest+Airport/@47.4183176,19.2539053,13z/data=!4m2!3m1!1s0x4741c1a4fe39860b:0x4ca4f6a650439aa1 Liszt Ferenc Airport] by public transport: [http://bud.hu/english/passengers/access_and_parking/by_public_transportation 200E Bus] and [http://www.bkk.hu/en/timetables/#M3 M3 (Metro line 3 or blue line)].<br />
<br />
=== Getting to the venue ===<br />
<br />
The Gizmodo Media Group's offices ([https://www.google.com/maps/d/viewer?mid=1AyxcMMg-WojQnb7b9OMdkqu-QeU&hl=en 1062 Budapest, Andrássy út 66.]) are near center of the city, so it can be easily approached even by foot from downtown accommodations.<br />
For public transport timetables, and more information please visit the local transport authority’s [http://www.bkk.hu/en/main-page/news/ site].<br />
<br/><br />
'''Information about tickets, and recommended tickets:'''<br />
<br />
* [http://www.bkk.hu/en/prices/ Local Transport Tikets and Passes]<br />
* [http://www.bkk.hu/en/block-of-10-tickets/ Block of 10 tickets]<br />
* [http://www.bkk.hu/en/budapest-72-hour-travel-card/ Budapest 72-hour travel card]<br />
<br />
'''Local Taxis''':<br />
* [http://bud.hu/english/passengers/access_and_parking/by_taxi Airport Taxi Information]<br />
* [http://www.tripadvisor.com/Travel-g274887-c167515/Budapest:Hungary:A.Tip.Budapest.Taxi.Fares.And.Advice.html Budapest taxi information (tripadvisor.com)]<br />
* [http://www.budapest.com/travel/getting_around/taxi.en.html List of Taxi companies]<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.k9residence.com/ K9 Residence] (In the city center, from 40 euro/night)<br />
* [https://www.airbnb.com/s/Budapest--Hungary/homes?allow_override%5B%5D=&checkin=2017-07-23&checkout=2017-07-31 Airbnb]<br />
* [http://www.only-apartments.com/apartments-budapest.html OnlyApartments.com]<br />
* [http://www.holidaylettings.co.uk/budapest/ HolidayLettings]<br />
* [http://www.bbhostel.hu/ Budapest Budget Hostel]<br />
* [http://www.hostelworld.com/search?search_keywords=Budapest%2C+Hungary&country=Hungary&city=Budapest&date_from=2014-05-30&date_to=2014-06-02 HostelWorld]<br />
<br />
== Schedule ==<br />
<br />
''Note:'' This is only an approximate schedule.<br />
<br />
{| class="wikitable"<br />
|-<br />
! !! Saturday !! Sunday<br />
|-<br />
| 9:00 || doors open || doors open<br />
|-<br />
| 9:30 || ''Andres Löh'' <br/> '''generics-sop''' || ''András Leitereg, Dániel Berényi'' <br/> '''LambdaGen: A GPU Code Generator Powered by Recursion Schemes'''<br />
|-<br />
| 10:10 || short break || short break<br />
|-<br />
| 10:20 || ''Michal Kawalec'' <br/> '''Functional programming with bananas in barbed wire''' || '''Lightning talks'''<br />
|-<br />
| 11:00 || project discussions, start of project work || project discussions, start of project work<br />
|-<br />
| 13:30 || lunch break || lunch break<br />
|-<br />
| 16:30 || || demo session<br />
|-<br />
| 17:00 || end of scheduled programs, beers || end of scheduled programs, beers<br />
|}<br />
<br />
== Projects ==<br />
<br />
=== generics-sop: Generic Programming using True Sums of Products ===<br />
<br />
'''Description'''<br />
<br />
generics-sop is a library for datatype-generic programming in Haskell. <br />
Datatypes are viewed as n-ary sums of n-ary products. Such sums and <br />
products are represented in a type-safe way using Haskell GADTs and <br />
manipulated via higher-rank polymorphic combinators provided by the <br />
library. <br />
<br />
The core of the library is relatively stable, but some new features, <br />
such as type-level metadata, require more experience to stabilize. <br />
So one open task is to just experiment with type-level metadata and <br />
provide feedback. <br />
<br />
Other tasks are improving the documentation, and creating a systematic <br />
benchmark suite so that the performance of generics-sop can be measured <br />
and the performance of different existing internal representations can <br />
be compared with each other. <br />
<br />
'''Contact''': Andres Löh<br />
<br />
'''Homepage''': https://github.com/well-typed/generics-sop<br />
<br />
=== hs-di ===<br />
<br />
'''Description''': Dependency Injection library for Haskell to allow powerful unit testing and mocking (compile-time type-checked)<br />
<br />
'''Contact''': Milan Nagy<br />
<br />
'''Homepage''': https://hackage.haskell.org/package/hs-di<br />
<br />
=== STG Optimisations ===<br />
<br />
'''Description''': Since the GHC's internal STG language is unityped, the runtime representation of `\case Right a → Just a` is the strict identity (`\ !a → a`) operationally. However, this optimisation currently is not implemented. Something similar is already done, so this might be low-hanging fruit.<br />
<br />
'''Contact''': Gabor Greif<br />
<br />
'''Homepage''': https://ghc.haskell.org/trac/ghc/ticket/13861<br />
<br />
== Talks/demos ==<br />
<br />
As of yet the following talks are scheduled:<br/><br />
<br />
=== Andres Löh - generics-sop ===<br />
<br />
'''Abstract'''<br />
<br />
Datatype-generic programming and generics-sop provides access to the <br />
internal structure of datatype definitions, allowing functions to <br />
access datatype constructors and their arguments in a uniform yet <br />
type-safe way. As a result, we can implement functions that work over <br />
a large range of datatypes and are typically built into the compiler <br />
as "derivable" classes directly within Haskell, such as equality and <br />
comparison functions, (de)serialization functions to various formats, <br />
or generic traversals such as maps and folds. <br />
<br />
We will look at a number of examples and show how they can be solved <br />
with generics-sop.<br />
<br />
'''Talk/Project repo'''<br />
<br />
https://hackage.haskell.org/package/generics-sop<br />
<br />
'''Presenter'''<br />
<br />
Andres is a partner and Haskell Consultant at [http://www.well-typed.com Well-Typed LLP].<br />
<br />
=== András Leitereg, Dániel Berényi - LambdaGen: A GPU Code Generator Powered by Recursion Schemes ===<br />
<br />
'''Abstract'''<br />
<br />
Problems that are data and computation intensive but are also naturally parallelizable are very frequent in physics, statistics and other fields of science. Their efficient parallel implementation would however require not just decent programming skills, but also deep insight of the target architecture. These computations are often in the form of a linear algebraic expression, and our goal is to deduce their optimal parallelization and memory usage automatically. We'd like to create a tool that offers a compromise between minimizing the implementation and the running time, for scientists who are not programmers.<br />
We chose a small set of high level operations accessible through a Haskell EDSL, with which the users build an expression tree of their computation. Then we apply a series of recursion scheme based transformations on the expression tree, and finally produce a [https://www.khronos.org/sycl SYCL] source code to evaluate the expression on GPU. We keep this abstract representation throughout the processing, which opens the possibility of optimizations that are otherwise difficult to recognize and carry out. It also minimizes the time we spent with debugging, but imposes some problems that are specific to the functional context.<br />
<br />
'''Talk/Project repo'''<br />
<br />
* https://github.com/leanil/LambdaGen<br />
<br />
'''Presenters'''<br />
<br />
* András Leitereg (Department of Informatics, Eötvös Loránd University)<br />
* Dániel Berényi (Wigner GPU Lab)<br />
<br />
=== Michal Kawalec - Functional programming with bananas in barbed wire ===<br />
<br />
''' Proposal '''<br />
<br />
In our day to day functional programming, we encounter recursion every<br />
step of the way. If only there were a way of abstracting away its<br />
repetitive parts and clarifying the recursive code with minimal<br />
boilerplate!<br />
<br />
Fortunately, recursion schemes come to the rescue. They allow for a<br />
clear and concise definition of recursion, while being guided by the<br />
typechecker. The talk will present basic theory behind them but will not<br />
require advanced knowledge of mathematics. We believe that recursion<br />
schemes can greatly benefit from a more widespread usage and will try to<br />
convey the practical ways in which they can be used in real life<br />
programs.<br />
<br />
''' Bio '''<br />
<br />
Michal is an engineer of many trades. He is currently responsible for<br />
libraries and architecture of League of Legends, and, previously, he had worked<br />
with startups, supercomputers, and particle detectors. At night, he<br />
writes Haskell libraries and runs the biggest Haskell Meetup in Poland.<br />
<br />
=== Notes regarding the talks ===<br />
<br />
We plan more, and we will update this site regularly so check back later.<br />
<br />
Apart from longer presentations, it will be possible to give lightning talks, or project demos. If you're interested in giving one of these, please contact us on one of the addresses at the bottom of the page.<br />
<br />
== Attendees ==<br />
<br />
Here is the [[/Attendees|list of participants]] who have signed up, and have chosen their name to be listed.<br />
<br />
== Communication ==<br />
<br />
If you have any questions about the event you can reach us here:<br />
<br />
* E-mail: [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
* Twitter: [http://twitter.com/bp_hug @bp_hug]<br />
* Gitter: [https://gitter.im/BP-HUG BP-HUG]<br />
* Meetup: [http://meetup.com/Bp-HUG/ Budapest Haskell User Group]<br />
<br />
All code from this and past event will be uploaded to the meetup’s [https://github.com/BP-HUG/ Github page].<br />
<br />
== Organizers ==<br />
<br />
* Dániel Berecz<br />
* Csaba Hruska<br />
* Péter Diviánszky<br />
* Andor Pénzes<br />
<br />
== Code of Conduct ==<br />
<br />
All attendees, speakers, exhibitors, organizers, contributors and volunteers are required to conform to the following Code of Conduct.<br />
<br />
BP-HUG events are for anyone interested in the Haskell language, its history, related topics, and want to discuss them in a fun, engaging and respectful environment.<br />
<br />
'''Be an adult, don't be a jerk.'''<br />
<br />
We value the participation of each member of the community and want all attendees to have an enjoyable and fulfilling experience. Accordingly, all attendees are expected to show respect and courtesy to other attendees throughout the meet-ups, this hackathon, and on the electronic channels listed above.<br />
<br />
=== Need help? ===<br />
<br />
If you are experiencing harassment on or have concerns about the content please contact:<br />
<br />
* '''Dániel Berecz:''' dαniεl.bεrεcz@gmαil.com (replace the greek letters)<br />
* '''All:''' [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
<br />
The organizers will be available to help you with any issues or concerns at this event.<br />
<br />
=== What it means ===<br />
<br />
The BP-HUG is dedicated to providing a harassment-free experience for everyone, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of meet-up participants in any form.<br />
<br />
All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate for any meet-up, including talks.<br />
<br />
Be kind to others. Do not insult or put down other attendees. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for this event.<br />
<br />
Attendees violating these rules may be asked to leave the meet-up at the sole discretion of the organizers.<br />
<br />
Thank you for helping make this a welcoming, friendly event for all.<br />
<br />
=== Spelling it out ===<br />
<br />
Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, religion, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.<br />
<br />
Participants asked to stop any harassing behavior are expected to comply immediately.<br />
<br />
Contributors to the GitHub repository, the Meetup and/or event-related sites, sponsors, or similar are also subject to the anti-harassment policy. Organizers (including volunteers) should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Budapest_Hackathon_2017&diff=62025Budapest Hackathon 20172017-07-28T04:10:41Z<p>Heisenbug: /* Registration */</p>
<hr />
<div>[[File:Bp hh 2017.png|768px]]<br />
<br />
[[File:Budapest01.jpg|300px|right]]<br />
[[File:BudapestPub01.jpg|300px|right]]<br />
[[File:BudapestPub02.jpg|300px|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|2017July 29 - 30th (Saturday & Sunday)<br />
|-<br />
|Hours:<br />
|09:00 ~ 17:00<br />
|-<br />
|Where:<br />
|[https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media Hungary, 1062 Andrássy út 66.]<br />
|}<br />
----<br />
<br />
<br />
== About ==<br />
<br />
[https://meetup.com/Bp-HUG/ The Budapest Haskell User Group] will once again hold a two day Haskell Hackathon in Budapest. This is the third the occasion (info about [https://wiki.haskell.org/BudapestHackathon2014 the first], [https://wiki.haskell.org/Budapest_Hackathon_2016 and second hackathon]), and this time we will hold it in Gizmodo Media Group's Budapest office.<br />
The event is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure, and growing the local community.<br />
<br />
This is a great opportunity to meet your fellow Haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones!<br />
<br />
This event is open to any experience level, from beginners to gurus. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community. We will have a dedicated beginners' track, and there are going to be experienced haskellers on site whom you can directly approach during the whole event with any Haskell-related question that might pop up.<br />
<br />
There will be lots of hacking, good food, and, of course, fun!<br />
<br />
<p><br />
<br />
== Sponsors ==<br />
<br />
[[File:Gmg logo.png|center|200px]]<br />
[[File:Digital asset logo.png|center|400px]]<br />
[[File:Iseeq logo.png|center|250px]]<br />
<br />
Many thanks to [http://gizmodo.com/careers/budapest#openings GMG] for hosting, and [https://digitalasset.com Digital Asset], and [http://iseeq.co IseeQ] for sponsoring the event.<br />
<br />
== Registration ==<br />
<br />
You can fill out the necessary registration information [https://goo.gl/forms/QjTNdXTD1aEOMEQU2 here]. <br/>There is no registration deadline, or requirement really, so you can join us even if you didn't fill out the form, it just helps us with the organization.<br />
<br />
== Venue ==<br />
<br />
[[File:a66_front.jpg|300px|right]]<br />
[[File:a66_inside_1.jpg|300px|right]]<br />
[[File:a66_inside_2.jpg|300px|right]]<br />
<br />
The Hackathon will be held at [https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media's Budapest office]. WiFi, projectors for talks, and snacks & refreshments will be provided by our sponsors.<br/><br />
Detailed schedules will be posted soon.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Budapest ===<br />
You can find out more about [http://www.budapest.com/ Budapest] on [http://wikitravel.org/en/Budapest these] [https://www.tripadvisor.com/Tourism-g274887-Budapest_Central_Hungary-Vacations.html sites]. Travel informations can be found on [http://bud.hu/english bud.hu].<br />
<br />
==== By Plane ====<br />
<br />
From [https://www.google.com/maps/place/Budapest+Airport/@47.4183176,19.2539053,13z/data=!4m2!3m1!1s0x4741c1a4fe39860b:0x4ca4f6a650439aa1 Liszt Ferenc Airport] by public transport: [http://bud.hu/english/passengers/access_and_parking/by_public_transportation 200E Bus] and [http://www.bkk.hu/en/timetables/#M3 M3 (Metro line 3 or blue line)].<br />
<br />
=== Getting to the venue ===<br />
<br />
The Gizmodo Media Group's offices ([https://www.google.com/maps/d/viewer?mid=1AyxcMMg-WojQnb7b9OMdkqu-QeU&hl=en 1062 Budapest, Andrássy út 66.]) are near center of the city, so it can be easily approached even by foot from downtown accommodations.<br />
For public transport timetables, and more informations please visit the local transport authority’s [http://www.bkk.hu/en/main-page/news/ site].<br />
<br/><br />
'''Information about tickets, and recommended tickets:'''<br />
<br />
* [http://www.bkk.hu/en/prices/ Local Transport Tikets and Passes]<br />
* [http://www.bkk.hu/en/block-of-10-tickets/ Block of 10 tickets]<br />
* [http://www.bkk.hu/en/budapest-72-hour-travel-card/ Budapest 72-hour travel card]<br />
<br />
'''Local Taxis''':<br />
* [http://bud.hu/english/passengers/access_and_parking/by_taxi Airport Taxi Information]<br />
* [http://www.tripadvisor.com/Travel-g274887-c167515/Budapest:Hungary:A.Tip.Budapest.Taxi.Fares.And.Advice.html Budapest taxi information (tripadvisor.com)]<br />
* [http://www.budapest.com/travel/getting_around/taxi.en.html List of Taxi companies]<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.k9residence.com/ K9 Residence] (In the city center, from 40 euro/night)<br />
* [https://www.airbnb.com/s/Budapest--Hungary/homes?allow_override%5B%5D=&checkin=2017-07-23&checkout=2017-07-31 Airbnb]<br />
* [http://www.only-apartments.com/apartments-budapest.html OnlyApartments.com]<br />
* [http://www.holidaylettings.co.uk/budapest/ HolidayLettings]<br />
* [http://www.bbhostel.hu/ Budapest Budget Hostel]<br />
* [http://www.hostelworld.com/search?search_keywords=Budapest%2C+Hungary&country=Hungary&city=Budapest&date_from=2014-05-30&date_to=2014-06-02 HostelWorld]<br />
<br />
== Schedule ==<br />
<br />
''Note:'' This is only an approximate schedule.<br />
<br />
{| class="wikitable"<br />
|-<br />
! !! Saturday !! Sunday<br />
|-<br />
| 9:00 || doors open || doors open<br />
|-<br />
| 9:30 || ''Andres Löh'' <br/> '''generics-sop''' || ''András Leitereg, Dániel Berényi'' <br/> '''LambdaGen: A GPU Code Generator Powered by Recursion Schemes'''<br />
|-<br />
| 10:10 || short break || short break<br />
|-<br />
| 10:20 || ''Michal Kawalec'' <br/> '''Functional programming with bananas in barbed wire''' || '''Lightning talks'''<br />
|-<br />
| 11:00 || project discussions, start of project work || project discussions, start of project work<br />
|-<br />
| 13:30 || lunch break || lunch break<br />
|-<br />
| 16:30 || || demo session<br />
|-<br />
| 17:00 || end of scheduled programs, beers || end of scheduled programs, beers<br />
|}<br />
<br />
== Projects ==<br />
<br />
=== generics-sop: Generic Programming using True Sums of Products ===<br />
<br />
'''Description'''<br />
<br />
generics-sop is a library for datatype-generic programming in Haskell. <br />
Datatypes are viewed as n-ary sums of n-ary products. Such sums and <br />
products are represented in a type-safe way using Haskell GADTs and <br />
manipulated via higher-rank polymorphic combinators provided by the <br />
library. <br />
<br />
The core of the library is relatively stable, but some new features, <br />
such as type-level metadata, require more experience to stabilize. <br />
So one open task is to just experiment with type-level metadata and <br />
provide feedback. <br />
<br />
Other tasks are improving the documentation, and creating a systematic <br />
benchmark suite so that the performance of generics-sop can be measured <br />
and the performance of different existing internal representations can <br />
be compared with each other. <br />
<br />
'''Contact''': Andres Löh<br />
<br />
'''Homepage''': https://github.com/well-typed/generics-sop<br />
<br />
=== hs-di ===<br />
<br />
'''Description''': Dependency Injection library for Haskell to allow powerful unit testing and mocking (compile-time type-checked)<br />
<br />
'''Contact''': Milan Nagy<br />
<br />
'''Homepage''': https://hackage.haskell.org/package/hs-di<br />
<br />
=== STG Optimisations ===<br />
<br />
'''Description''': Since the GHC's internal STG language is unityped, the runtime representation of `\case Right a → Just a` is the strict identity (`\ !a → a`) operationally. However, this optimisation currently is not implemented. Something similar is already done, so this might be low-hanging fruit.<br />
<br />
'''Contact''': Gabor Greif<br />
<br />
'''Homepage''': https://ghc.haskell.org/trac/ghc/ticket/13861<br />
<br />
== Talks/demos ==<br />
<br />
As of yet the following talks are scheduled:<br/><br />
<br />
=== Andres Löh - generics-sop ===<br />
<br />
'''Abstract'''<br />
<br />
Datatype-generic programming and generics-sop provides access to the <br />
internal structure of datatype definitions, allowing functions to <br />
access datatype constructors and their arguments in a uniform yet <br />
type-safe way. As a result, we can implement functions that work over <br />
a large range of datatypes and are typically built into the compiler <br />
as "derivable" classes directly within Haskell, such as equality and <br />
comparison functions, (de)serialization functions to various formats, <br />
or generic traversals such as maps and folds. <br />
<br />
We will look at a number of examples and show how they can be solved <br />
with generics-sop.<br />
<br />
'''Talk/Project repo'''<br />
<br />
https://hackage.haskell.org/package/generics-sop<br />
<br />
'''Presenter'''<br />
<br />
Andres is a partner and Haskell Consultant at [http://www.well-typed.com Well-Typed LLP].<br />
<br />
=== András Leitereg, Dániel Berényi - LambdaGen: A GPU Code Generator Powered by Recursion Schemes ===<br />
<br />
'''Abstract'''<br />
<br />
Problems that are data and computation intensive but are also naturally parallelizable are very frequent in physics, statistics and other fields of science. Their efficient parallel implementation would however require not just decent programming skills, but also deep insight of the target architecture. These computations are often in the form of a linear algebraic expression, and our goal is to deduce their optimal parallelization and memory usage automatically. We'd like to create a tool that offers a compromise between minimizing the implementation and the running time, for scientists who are not programmers.<br />
We chose a small set of high level operations accessible through a Haskell EDSL, with which the users build an expression tree of their computation. Then we apply a series of recursion scheme based transformations on the expression tree, and finally produce a [https://www.khronos.org/sycl SYCL] source code to evaluate the expression on GPU. We keep this abstract representation throughout the processing, which opens the possibility of optimizations that are otherwise difficult to recognize and carry out. It also minimizes the time we spent with debugging, but imposes some problems that are specific to the functional context.<br />
<br />
'''Talk/Project repo'''<br />
<br />
* https://github.com/leanil/LambdaGen<br />
<br />
'''Presenters'''<br />
<br />
* András Leitereg (Department of Informatics, Eötvös Loránd University)<br />
* Dániel Berényi (Wigner GPU Lab)<br />
<br />
=== Michal Kawalec - Functional programming with bananas in barbed wire ===<br />
<br />
''' Proposal '''<br />
<br />
In our day to day functional programming, we encounter recursion every<br />
step of the way. If only there were a way of abstracting away its<br />
repetitive parts and clarifying the recursive code with minimal<br />
boilerplate!<br />
<br />
Fortunately, recursion schemes come to the rescue. They allow for a<br />
clear and concise definition of recursion, while being guided by the<br />
typechecker. The talk will present basic theory behind them but will not<br />
require advanced knowledge of mathematics. We believe that recursion<br />
schemes can greatly benefit from a more widespread usage and will try to<br />
convey the practical ways in which they can be used in real life<br />
programs.<br />
<br />
''' Bio '''<br />
<br />
Michal is an engineer of many trades. He is currently responsible for<br />
libraries and architecture of League of Legends, and, previously, he had worked<br />
with startups, supercomputers, and particle detectors. At night, he<br />
writes Haskell libraries and runs the biggest Haskell Meetup in Poland.<br />
<br />
=== Notes regarding the talks ===<br />
<br />
We plan more, and we will update this site regularly so check back later.<br />
<br />
Apart from longer presentations, it will be possible to give lightning talks, or project demos. If you're interested in giving one of these, please contact us on one of the addresses at the bottom of the page.<br />
<br />
== Attendees ==<br />
<br />
Here is the [[/Attendees|list of participants]] who have signed up, and have chosen their name to be listed.<br />
<br />
== Communication ==<br />
<br />
If you have any questions about the event you can reach us here:<br />
<br />
* E-mail: [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
* Twitter: [http://twitter.com/bp_hug @bp_hug]<br />
* Gitter: [https://gitter.im/BP-HUG BP-HUG]<br />
* Meetup: [http://meetup.com/Bp-HUG/ Budapest Haskell User Group]<br />
<br />
All code from this and past event will be uploaded to the meetup’s [https://github.com/BP-HUG/ Github page].<br />
<br />
== Organizers ==<br />
<br />
* Dániel Berecz<br />
* Csaba Hruska<br />
* Péter Diviánszky<br />
* Andor Pénzes<br />
<br />
== Code of Conduct ==<br />
<br />
All attendees, speakers, exhibitors, organizers, contributors and volunteers are required to conform to the following Code of Conduct.<br />
<br />
BP-HUG events are for anyone interested in the Haskell language, its history, related topics, and want to discuss them in a fun, engaging and respectful environment.<br />
<br />
'''Be an adult, don't be a jerk.'''<br />
<br />
We value the participation of each member of the community and want all attendees to have an enjoyable and fulfilling experience. Accordingly, all attendees are expected to show respect and courtesy to other attendees throughout the meet-ups, this hackathon, and on the electronic channels listed above.<br />
<br />
=== Need help? ===<br />
<br />
If you are experiencing harassment on or have concerns about the content please contact:<br />
<br />
* '''Dániel Berecz:''' dαniεl.bεrεcz@gmαil.com (replace the greek letters)<br />
* '''All:''' [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
<br />
The organizers will be available to help you with any issues or concerns at this event.<br />
<br />
=== What it means ===<br />
<br />
The BP-HUG is dedicated to providing a harassment-free experience for everyone, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of meet-up participants in any form.<br />
<br />
All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate for any meet-up, including talks.<br />
<br />
Be kind to others. Do not insult or put down other attendees. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for this event.<br />
<br />
Attendees violating these rules may be asked to leave the meet-up at the sole discretion of the organizers.<br />
<br />
Thank you for helping make this a welcoming, friendly event for all.<br />
<br />
=== Spelling it out ===<br />
<br />
Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, religion, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.<br />
<br />
Participants asked to stop any harassing behavior are expected to comply immediately.<br />
<br />
Contributors to the GitHub repository, the Meetup and/or event-related sites, sponsors, or similar are also subject to the anti-harassment policy. Organizers (including volunteers) should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Budapest_Hackathon_2017&diff=62024Budapest Hackathon 20172017-07-27T12:18:36Z<p>Heisenbug: strictly</p>
<hr />
<div>[[File:Bp hh 2017.png|768px]]<br />
<br />
[[File:Budapest01.jpg|300px|right]]<br />
[[File:BudapestPub01.jpg|300px|right]]<br />
[[File:BudapestPub02.jpg|300px|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|2017July 29 - 30th (Saturday & Sunday)<br />
|-<br />
|Hours:<br />
|09:00 ~ 17:00<br />
|-<br />
|Where:<br />
|[https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media Hungary, 1062 Andrássy út 66.]<br />
|}<br />
----<br />
<br />
<br />
== About ==<br />
<br />
[https://meetup.com/Bp-HUG/ The Budapest Haskell User Group] will once again hold a two day Haskell Hackathon in Budapest. This is the third the occasion (info about [https://wiki.haskell.org/BudapestHackathon2014 the first], [https://wiki.haskell.org/Budapest_Hackathon_2016 and second hackathon]), and this time we will hold it in Gizmodo Media Group's Budapest office.<br />
The event is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure, and growing the local community.<br />
<br />
This is a great opportunity to meet your fellow Haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones!<br />
<br />
This event is open to any experience level, from beginners to gurus. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community. We will have a dedicated beginners' track, and there are going to be experienced haskellers on site whom you can directly approach during the whole event with any Haskell-related question that might pop up.<br />
<br />
There will be lots of hacking, good food, and, of course, fun!<br />
<br />
<p><br />
<br />
== Sponsors ==<br />
<br />
[[File:Gmg logo.png|center|200px]]<br />
[[File:Digital asset logo.png|center|400px]]<br />
[[File:Iseeq logo.png|center|250px]]<br />
<br />
Many thanks to [http://gizmodo.com/careers/budapest#openings GMG] for hosting, and [https://digitalasset.com Digital Asset], and [http://iseeq.co IseeQ] for sponsoring the event.<br />
<br />
== Registration ==<br />
<br />
You can fill out the necessary registration information [https://goo.gl/forms/QjTNdXTD1aEOMEQU2 here]. <br/>There is no registration deadline, or requirement really, so you can join us even if you didn't fill out the form, it just help us with the organization.<br />
<br />
== Venue ==<br />
<br />
[[File:a66_front.jpg|300px|right]]<br />
[[File:a66_inside_1.jpg|300px|right]]<br />
[[File:a66_inside_2.jpg|300px|right]]<br />
<br />
The Hackathon will be held at [https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media's Budapest office]. WiFi, projectors for talks, and snacks & refreshments will be provided by our sponsors.<br/><br />
Detailed schedules will be posted soon.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Budapest ===<br />
You can find out more about [http://www.budapest.com/ Budapest] on [http://wikitravel.org/en/Budapest these] [https://www.tripadvisor.com/Tourism-g274887-Budapest_Central_Hungary-Vacations.html sites]. Travel informations can be found on [http://bud.hu/english bud.hu].<br />
<br />
==== By Plane ====<br />
<br />
From [https://www.google.com/maps/place/Budapest+Airport/@47.4183176,19.2539053,13z/data=!4m2!3m1!1s0x4741c1a4fe39860b:0x4ca4f6a650439aa1 Liszt Ferenc Airport] by public transport: [http://bud.hu/english/passengers/access_and_parking/by_public_transportation 200E Bus] and [http://www.bkk.hu/en/timetables/#M3 M3 (Metro line 3 or blue line)].<br />
<br />
=== Getting to the venue ===<br />
<br />
The Gizmodo Media Group's offices ([https://www.google.com/maps/d/viewer?mid=1AyxcMMg-WojQnb7b9OMdkqu-QeU&hl=en 1062 Budapest, Andrássy út 66.]) are near center of the city, so it can be easily approached even by foot from downtown accommodations.<br />
For public transport timetables, and more informations please visit the local transport authority’s [http://www.bkk.hu/en/main-page/news/ site].<br />
<br/><br />
'''Information about tickets, and recommended tickets:'''<br />
<br />
* [http://www.bkk.hu/en/prices/ Local Transport Tikets and Passes]<br />
* [http://www.bkk.hu/en/block-of-10-tickets/ Block of 10 tickets]<br />
* [http://www.bkk.hu/en/budapest-72-hour-travel-card/ Budapest 72-hour travel card]<br />
<br />
'''Local Taxis''':<br />
* [http://bud.hu/english/passengers/access_and_parking/by_taxi Airport Taxi Information]<br />
* [http://www.tripadvisor.com/Travel-g274887-c167515/Budapest:Hungary:A.Tip.Budapest.Taxi.Fares.And.Advice.html Budapest taxi information (tripadvisor.com)]<br />
* [http://www.budapest.com/travel/getting_around/taxi.en.html List of Taxi companies]<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.k9residence.com/ K9 Residence] (In the city center, from 40 euro/night)<br />
* [https://www.airbnb.com/s/Budapest--Hungary/homes?allow_override%5B%5D=&checkin=2017-07-23&checkout=2017-07-31 Airbnb]<br />
* [http://www.only-apartments.com/apartments-budapest.html OnlyApartments.com]<br />
* [http://www.holidaylettings.co.uk/budapest/ HolidayLettings]<br />
* [http://www.bbhostel.hu/ Budapest Budget Hostel]<br />
* [http://www.hostelworld.com/search?search_keywords=Budapest%2C+Hungary&country=Hungary&city=Budapest&date_from=2014-05-30&date_to=2014-06-02 HostelWorld]<br />
<br />
== Schedule ==<br />
<br />
''Note:'' This is only an approximate schedule.<br />
<br />
{| class="wikitable"<br />
|-<br />
! !! Saturday !! Sunday<br />
|-<br />
| 9:00 || doors open || doors open<br />
|-<br />
| 9:30 || ''Andres Löh'' <br/> '''generics-sop''' || ''András Leitereg, Dániel Berényi'' <br/> '''LambdaGen: A GPU Code Generator Powered by Recursion Schemes'''<br />
|-<br />
| 10:10 || short break || short break<br />
|-<br />
| 10:20 || ''Michal Kawalec'' <br/> '''Functional programming with bananas in barbed wire''' || '''Lightning talks'''<br />
|-<br />
| 11:00 || project discussions, start of project work || project discussions, start of project work<br />
|-<br />
| 13:30 || lunch break || lunch break<br />
|-<br />
| 16:30 || || demo session<br />
|-<br />
| 17:00 || end of scheduled programs, beers || end of scheduled programs, beers<br />
|}<br />
<br />
== Projects ==<br />
<br />
=== generics-sop: Generic Programming using True Sums of Products ===<br />
<br />
'''Description'''<br />
<br />
generics-sop is a library for datatype-generic programming in Haskell. <br />
Datatypes are viewed as n-ary sums of n-ary products. Such sums and <br />
products are represented in a type-safe way using Haskell GADTs and <br />
manipulated via higher-rank polymorphic combinators provided by the <br />
library. <br />
<br />
The core of the library is relatively stable, but some new features, <br />
such as type-level metadata, require more experience to stabilize. <br />
So one open task is to just experiment with type-level metadata and <br />
provide feedback. <br />
<br />
Other tasks are improving the documentation, and creating a systematic <br />
benchmark suite so that the performance of generics-sop can be measured <br />
and the performance of different existing internal representations can <br />
be compared with each other. <br />
<br />
'''Contact''': Andres Löh<br />
<br />
'''Homepage''': https://github.com/well-typed/generics-sop<br />
<br />
=== hs-di ===<br />
<br />
'''Description''': Dependency Injection library for Haskell to allow powerful unit testing and mocking (compile-time type-checked)<br />
<br />
'''Contact''': Milan Nagy<br />
<br />
'''Homepage''': https://hackage.haskell.org/package/hs-di<br />
<br />
=== STG Optimisations ===<br />
<br />
'''Description''': Since the GHC's internal STG language is unityped, the runtime representation of `\case Right a → Just a` is the strict identity (`\ !a → a`) operationally. However, this optimisation currently is not implemented. Something similar is already done, so this might be low-hanging fruit.<br />
<br />
'''Contact''': Gabor Greif<br />
<br />
'''Homepage''': https://ghc.haskell.org/trac/ghc/ticket/13861<br />
<br />
== Talks/demos ==<br />
<br />
As of yet the following talks are scheduled:<br/><br />
<br />
=== Andres Löh - generics-sop ===<br />
<br />
'''Abstract'''<br />
<br />
Datatype-generic programming and generics-sop provides access to the <br />
internal structure of datatype definitions, allowing functions to <br />
access datatype constructors and their arguments in a uniform yet <br />
type-safe way. As a result, we can implement functions that work over <br />
a large range of datatypes and are typically built into the compiler <br />
as "derivable" classes directly within Haskell, such as equality and <br />
comparison functions, (de)serialization functions to various formats, <br />
or generic traversals such as maps and folds. <br />
<br />
We will look at a number of examples and show how they can be solved <br />
with generics-sop.<br />
<br />
'''Talk/Project repo'''<br />
<br />
https://hackage.haskell.org/package/generics-sop<br />
<br />
'''Presenter'''<br />
<br />
Andres is a partner and Haskell Consultant at [http://www.well-typed.com Well-Typed LLP].<br />
<br />
=== András Leitereg, Dániel Berényi - LambdaGen: A GPU Code Generator Powered by Recursion Schemes ===<br />
<br />
'''Abstract'''<br />
<br />
Problems that are data and computation intensive but are also naturally parallelizable are very frequent in physics, statistics and other fields of science. Their efficient parallel implementation would however require not just decent programming skills, but also deep insight of the target architecture. These computations are often in the form of a linear algebraic expression, and our goal is to deduce their optimal parallelization and memory usage automatically. We'd like to create a tool that offers a compromise between minimizing the implementation and the running time, for scientists who are not programmers.<br />
We chose a small set of high level operations accessible through a Haskell EDSL, with which the users build an expression tree of their computation. Then we apply a series of recursion scheme based transformations on the expression tree, and finally produce a [https://www.khronos.org/sycl SYCL] source code to evaluate the expression on GPU. We keep this abstract representation throughout the processing, which opens the possibility of optimizations that are otherwise difficult to recognize and carry out. It also minimizes the time we spent with debugging, but imposes some problems that are specific to the functional context.<br />
<br />
'''Talk/Project repo'''<br />
<br />
* https://github.com/leanil/LambdaGen<br />
<br />
'''Presenters'''<br />
<br />
* András Leitereg (Department of Informatics, Eötvös Loránd University)<br />
* Dániel Berényi (Wigner GPU Lab)<br />
<br />
=== Michal Kawalec - Functional programming with bananas in barbed wire ===<br />
<br />
''' Proposal '''<br />
<br />
In our day to day functional programming, we encounter recursion every<br />
step of the way. If only there were a way of abstracting away its<br />
repetitive parts and clarifying the recursive code with minimal<br />
boilerplate!<br />
<br />
Fortunately, recursion schemes come to the rescue. They allow for a<br />
clear and concise definition of recursion, while being guided by the<br />
typechecker. The talk will present basic theory behind them but will not<br />
require advanced knowledge of mathematics. We believe that recursion<br />
schemes can greatly benefit from a more widespread usage and will try to<br />
convey the practical ways in which they can be used in real life<br />
programs.<br />
<br />
''' Bio '''<br />
<br />
Michal is an engineer of many trades. He is currently responsible for<br />
libraries and architecture of League of Legends, and, previously, he had worked<br />
with startups, supercomputers, and particle detectors. At night, he<br />
writes Haskell libraries and runs the biggest Haskell Meetup in Poland.<br />
<br />
=== Notes regarding the talks ===<br />
<br />
We plan more, and we will update this site regularly so check back later.<br />
<br />
Apart from longer presentations, it will be possible to give lightning talks, or project demos. If you're interested in giving one of these, please contact us on one of the addresses at the bottom of the page.<br />
<br />
== Attendees ==<br />
<br />
Here is the [[/Attendees|list of participants]] who have signed up, and have chosen their name to be listed.<br />
<br />
== Communication ==<br />
<br />
If you have any questions about the event you can reach us here:<br />
<br />
* E-mail: [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
* Twitter: [http://twitter.com/bp_hug @bp_hug]<br />
* Gitter: [https://gitter.im/BP-HUG BP-HUG]<br />
* Meetup: [http://meetup.com/Bp-HUG/ Budapest Haskell User Group]<br />
<br />
All code from this and past event will be uploaded to the meetup’s [https://github.com/BP-HUG/ Github page].<br />
<br />
== Organizers ==<br />
<br />
* Dániel Berecz<br />
* Csaba Hruska<br />
* Péter Diviánszky<br />
* Andor Pénzes<br />
<br />
== Code of Conduct ==<br />
<br />
All attendees, speakers, exhibitors, organizers, contributors and volunteers are required to conform to the following Code of Conduct.<br />
<br />
BP-HUG events are for anyone interested in the Haskell language, its history, related topics, and want to discuss them in a fun, engaging and respectful environment.<br />
<br />
'''Be an adult, don't be a jerk.'''<br />
<br />
We value the participation of each member of the community and want all attendees to have an enjoyable and fulfilling experience. Accordingly, all attendees are expected to show respect and courtesy to other attendees throughout the meet-ups, this hackathon, and on the electronic channels listed above.<br />
<br />
=== Need help? ===<br />
<br />
If you are experiencing harassment on or have concerns about the content please contact:<br />
<br />
* '''Dániel Berecz:''' dαniεl.bεrεcz@gmαil.com (replace the greek letters)<br />
* '''All:''' [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
<br />
The organizers will be available to help you with any issues or concerns at this event.<br />
<br />
=== What it means ===<br />
<br />
The BP-HUG is dedicated to providing a harassment-free experience for everyone, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of meet-up participants in any form.<br />
<br />
All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate for any meet-up, including talks.<br />
<br />
Be kind to others. Do not insult or put down other attendees. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for this event.<br />
<br />
Attendees violating these rules may be asked to leave the meet-up at the sole discretion of the organizers.<br />
<br />
Thank you for helping make this a welcoming, friendly event for all.<br />
<br />
=== Spelling it out ===<br />
<br />
Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, religion, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.<br />
<br />
Participants asked to stop any harassing behavior are expected to comply immediately.<br />
<br />
Contributors to the GitHub repository, the Meetup and/or event-related sites, sponsors, or similar are also subject to the anti-harassment policy. Organizers (including volunteers) should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Budapest_Hackathon_2017&diff=62023Budapest Hackathon 20172017-07-27T12:11:29Z<p>Heisenbug: </p>
<hr />
<div>[[File:Bp hh 2017.png|768px]]<br />
<br />
[[File:Budapest01.jpg|300px|right]]<br />
[[File:BudapestPub01.jpg|300px|right]]<br />
[[File:BudapestPub02.jpg|300px|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|2017July 29 - 30th (Saturday & Sunday)<br />
|-<br />
|Hours:<br />
|09:00 ~ 17:00<br />
|-<br />
|Where:<br />
|[https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media Hungary, 1062 Andrássy út 66.]<br />
|}<br />
----<br />
<br />
<br />
== About ==<br />
<br />
[https://meetup.com/Bp-HUG/ The Budapest Haskell User Group] will once again hold a two day Haskell Hackathon in Budapest. This is the third the occasion (info about [https://wiki.haskell.org/BudapestHackathon2014 the first], [https://wiki.haskell.org/Budapest_Hackathon_2016 and second hackathon]), and this time we will hold it in Gizmodo Media Group's Budapest office.<br />
The event is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure, and growing the local community.<br />
<br />
This is a great opportunity to meet your fellow Haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones!<br />
<br />
This event is open to any experience level, from beginners to gurus. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community. We will have a dedicated beginners' track, and there are going to be experienced haskellers on site whom you can directly approach during the whole event with any Haskell-related question that might pop up.<br />
<br />
There will be lots of hacking, good food, and, of course, fun!<br />
<br />
<p><br />
<br />
== Sponsors ==<br />
<br />
[[File:Gmg logo.png|center|200px]]<br />
[[File:Digital asset logo.png|center|400px]]<br />
[[File:Iseeq logo.png|center|250px]]<br />
<br />
Many thanks to [http://gizmodo.com/careers/budapest#openings GMG] for hosting, and [https://digitalasset.com Digital Asset], and [http://iseeq.co IseeQ] for sponsoring the event.<br />
<br />
== Registration ==<br />
<br />
You can fill out the necessary registration information [https://goo.gl/forms/QjTNdXTD1aEOMEQU2 here]. <br/>There is no registration deadline, or requirement really, so you can join us even if you didn't fill out the form, it just help us with the organization.<br />
<br />
== Venue ==<br />
<br />
[[File:a66_front.jpg|300px|right]]<br />
[[File:a66_inside_1.jpg|300px|right]]<br />
[[File:a66_inside_2.jpg|300px|right]]<br />
<br />
The Hackathon will be held at [https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media's Budapest office]. WiFi, projectors for talks, and snacks & refreshments will be provided by our sponsors.<br/><br />
Detailed schedules will be posted soon.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Budapest ===<br />
You can find out more about [http://www.budapest.com/ Budapest] on [http://wikitravel.org/en/Budapest these] [https://www.tripadvisor.com/Tourism-g274887-Budapest_Central_Hungary-Vacations.html sites]. Travel informations can be found on [http://bud.hu/english bud.hu].<br />
<br />
==== By Plane ====<br />
<br />
From [https://www.google.com/maps/place/Budapest+Airport/@47.4183176,19.2539053,13z/data=!4m2!3m1!1s0x4741c1a4fe39860b:0x4ca4f6a650439aa1 Liszt Ferenc Airport] by public transport: [http://bud.hu/english/passengers/access_and_parking/by_public_transportation 200E Bus] and [http://www.bkk.hu/en/timetables/#M3 M3 (Metro line 3 or blue line)].<br />
<br />
=== Getting to the venue ===<br />
<br />
The Gizmodo Media Group's offices ([https://www.google.com/maps/d/viewer?mid=1AyxcMMg-WojQnb7b9OMdkqu-QeU&hl=en 1062 Budapest, Andrássy út 66.]) are near center of the city, so it can be easily approached even by foot from downtown accommodations.<br />
For public transport timetables, and more informations please visit the local transport authority’s [http://www.bkk.hu/en/main-page/news/ site].<br />
<br/><br />
'''Information about tickets, and recommended tickets:'''<br />
<br />
* [http://www.bkk.hu/en/prices/ Local Transport Tikets and Passes]<br />
* [http://www.bkk.hu/en/block-of-10-tickets/ Block of 10 tickets]<br />
* [http://www.bkk.hu/en/budapest-72-hour-travel-card/ Budapest 72-hour travel card]<br />
<br />
'''Local Taxis''':<br />
* [http://bud.hu/english/passengers/access_and_parking/by_taxi Airport Taxi Information]<br />
* [http://www.tripadvisor.com/Travel-g274887-c167515/Budapest:Hungary:A.Tip.Budapest.Taxi.Fares.And.Advice.html Budapest taxi information (tripadvisor.com)]<br />
* [http://www.budapest.com/travel/getting_around/taxi.en.html List of Taxi companies]<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.k9residence.com/ K9 Residence] (In the city center, from 40 euro/night)<br />
* [https://www.airbnb.com/s/Budapest--Hungary/homes?allow_override%5B%5D=&checkin=2017-07-23&checkout=2017-07-31 Airbnb]<br />
* [http://www.only-apartments.com/apartments-budapest.html OnlyApartments.com]<br />
* [http://www.holidaylettings.co.uk/budapest/ HolidayLettings]<br />
* [http://www.bbhostel.hu/ Budapest Budget Hostel]<br />
* [http://www.hostelworld.com/search?search_keywords=Budapest%2C+Hungary&country=Hungary&city=Budapest&date_from=2014-05-30&date_to=2014-06-02 HostelWorld]<br />
<br />
== Schedule ==<br />
<br />
''Note:'' This is only an approximate schedule.<br />
<br />
{| class="wikitable"<br />
|-<br />
! !! Saturday !! Sunday<br />
|-<br />
| 9:00 || doors open || doors open<br />
|-<br />
| 9:30 || ''Andres Löh'' <br/> '''generics-sop''' || ''András Leitereg, Dániel Berényi'' <br/> '''LambdaGen: A GPU Code Generator Powered by Recursion Schemes'''<br />
|-<br />
| 10:10 || short break || short break<br />
|-<br />
| 10:20 || ''Michal Kawalec'' <br/> '''Functional programming with bananas in barbed wire''' || '''Lightning talks'''<br />
|-<br />
| 11:00 || project discussions, start of project work || project discussions, start of project work<br />
|-<br />
| 13:30 || lunch break || lunch break<br />
|-<br />
| 16:30 || || demo session<br />
|-<br />
| 17:00 || end of scheduled programs, beers || end of scheduled programs, beers<br />
|}<br />
<br />
== Projects ==<br />
<br />
=== generics-sop: Generic Programming using True Sums of Products ===<br />
<br />
'''Description'''<br />
<br />
generics-sop is a library for datatype-generic programming in Haskell. <br />
Datatypes are viewed as n-ary sums of n-ary products. Such sums and <br />
products are represented in a type-safe way using Haskell GADTs and <br />
manipulated via higher-rank polymorphic combinators provided by the <br />
library. <br />
<br />
The core of the library is relatively stable, but some new features, <br />
such as type-level metadata, require more experience to stabilize. <br />
So one open task is to just experiment with type-level metadata and <br />
provide feedback. <br />
<br />
Other tasks are improving the documentation, and creating a systematic <br />
benchmark suite so that the performance of generics-sop can be measured <br />
and the performance of different existing internal representations can <br />
be compared with each other. <br />
<br />
'''Contact''': Andres Löh<br />
<br />
'''Homepage''': https://github.com/well-typed/generics-sop<br />
<br />
=== hs-di ===<br />
<br />
'''Description''': Dependency Injection library for Haskell to allow powerful unit testing and mocking (compile-time type-checked)<br />
<br />
'''Contact''': Milan Nagy<br />
<br />
'''Homepage''': https://hackage.haskell.org/package/hs-di<br />
<br />
=== STG Optimisations ===<br />
<br />
'''Description''': Since the GHC's internal STG language is unityped, the runtime representation of `\case Right a → Just a` is the identity (`id`) operationally. However, this optimisation currently is not implemented. Something similar is already done, so this might be low-hanging fruit.<br />
<br />
'''Contact''': Gabor Greif<br />
<br />
'''Homepage''': https://ghc.haskell.org/trac/ghc/ticket/13861<br />
<br />
== Talks/demos ==<br />
<br />
As of yet the following talks are scheduled:<br/><br />
<br />
=== Andres Löh - generics-sop ===<br />
<br />
'''Abstract'''<br />
<br />
Datatype-generic programming and generics-sop provides access to the <br />
internal structure of datatype definitions, allowing functions to <br />
access datatype constructors and their arguments in a uniform yet <br />
type-safe way. As a result, we can implement functions that work over <br />
a large range of datatypes and are typically built into the compiler <br />
as "derivable" classes directly within Haskell, such as equality and <br />
comparison functions, (de)serialization functions to various formats, <br />
or generic traversals such as maps and folds. <br />
<br />
We will look at a number of examples and show how they can be solved <br />
with generics-sop.<br />
<br />
'''Talk/Project repo'''<br />
<br />
https://hackage.haskell.org/package/generics-sop<br />
<br />
'''Presenter'''<br />
<br />
Andres is a partner and Haskell Consultant at [http://www.well-typed.com Well-Typed LLP].<br />
<br />
=== András Leitereg, Dániel Berényi - LambdaGen: A GPU Code Generator Powered by Recursion Schemes ===<br />
<br />
'''Abstract'''<br />
<br />
Problems that are data and computation intensive but are also naturally parallelizable are very frequent in physics, statistics and other fields of science. Their efficient parallel implementation would however require not just decent programming skills, but also deep insight of the target architecture. These computations are often in the form of a linear algebraic expression, and our goal is to deduce their optimal parallelization and memory usage automatically. We'd like to create a tool that offers a compromise between minimizing the implementation and the running time, for scientists who are not programmers.<br />
We chose a small set of high level operations accessible through a Haskell EDSL, with which the users build an expression tree of their computation. Then we apply a series of recursion scheme based transformations on the expression tree, and finally produce a [https://www.khronos.org/sycl SYCL] source code to evaluate the expression on GPU. We keep this abstract representation throughout the processing, which opens the possibility of optimizations that are otherwise difficult to recognize and carry out. It also minimizes the time we spent with debugging, but imposes some problems that are specific to the functional context.<br />
<br />
'''Talk/Project repo'''<br />
<br />
* https://github.com/leanil/LambdaGen<br />
<br />
'''Presenters'''<br />
<br />
* András Leitereg (Department of Informatics, Eötvös Loránd University)<br />
* Dániel Berényi (Wigner GPU Lab)<br />
<br />
=== Michal Kawalec - Functional programming with bananas in barbed wire ===<br />
<br />
''' Proposal '''<br />
<br />
In our day to day functional programming, we encounter recursion every<br />
step of the way. If only there were a way of abstracting away its<br />
repetitive parts and clarifying the recursive code with minimal<br />
boilerplate!<br />
<br />
Fortunately, recursion schemes come to the rescue. They allow for a<br />
clear and concise definition of recursion, while being guided by the<br />
typechecker. The talk will present basic theory behind them but will not<br />
require advanced knowledge of mathematics. We believe that recursion<br />
schemes can greatly benefit from a more widespread usage and will try to<br />
convey the practical ways in which they can be used in real life<br />
programs.<br />
<br />
''' Bio '''<br />
<br />
Michal is an engineer of many trades. He is currently responsible for<br />
libraries and architecture of League of Legends, and, previously, he had worked<br />
with startups, supercomputers, and particle detectors. At night, he<br />
writes Haskell libraries and runs the biggest Haskell Meetup in Poland.<br />
<br />
=== Notes regarding the talks ===<br />
<br />
We plan more, and we will update this site regularly so check back later.<br />
<br />
Apart from longer presentations, it will be possible to give lightning talks, or project demos. If you're interested in giving one of these, please contact us on one of the addresses at the bottom of the page.<br />
<br />
== Attendees ==<br />
<br />
Here is the [[/Attendees|list of participants]] who have signed up, and have chosen their name to be listed.<br />
<br />
== Communication ==<br />
<br />
If you have any questions about the event you can reach us here:<br />
<br />
* E-mail: [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
* Twitter: [http://twitter.com/bp_hug @bp_hug]<br />
* Gitter: [https://gitter.im/BP-HUG BP-HUG]<br />
* Meetup: [http://meetup.com/Bp-HUG/ Budapest Haskell User Group]<br />
<br />
All code from this and past event will be uploaded to the meetup’s [https://github.com/BP-HUG/ Github page].<br />
<br />
== Organizers ==<br />
<br />
* Dániel Berecz<br />
* Csaba Hruska<br />
* Péter Diviánszky<br />
* Andor Pénzes<br />
<br />
== Code of Conduct ==<br />
<br />
All attendees, speakers, exhibitors, organizers, contributors and volunteers are required to conform to the following Code of Conduct.<br />
<br />
BP-HUG events are for anyone interested in the Haskell language, its history, related topics, and want to discuss them in a fun, engaging and respectful environment.<br />
<br />
'''Be an adult, don't be a jerk.'''<br />
<br />
We value the participation of each member of the community and want all attendees to have an enjoyable and fulfilling experience. Accordingly, all attendees are expected to show respect and courtesy to other attendees throughout the meet-ups, this hackathon, and on the electronic channels listed above.<br />
<br />
=== Need help? ===<br />
<br />
If you are experiencing harassment on or have concerns about the content please contact:<br />
<br />
* '''Dániel Berecz:''' dαniεl.bεrεcz@gmαil.com (replace the greek letters)<br />
* '''All:''' [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
<br />
The organizers will be available to help you with any issues or concerns at this event.<br />
<br />
=== What it means ===<br />
<br />
The BP-HUG is dedicated to providing a harassment-free experience for everyone, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of meet-up participants in any form.<br />
<br />
All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate for any meet-up, including talks.<br />
<br />
Be kind to others. Do not insult or put down other attendees. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for this event.<br />
<br />
Attendees violating these rules may be asked to leave the meet-up at the sole discretion of the organizers.<br />
<br />
Thank you for helping make this a welcoming, friendly event for all.<br />
<br />
=== Spelling it out ===<br />
<br />
Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, religion, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.<br />
<br />
Participants asked to stop any harassing behavior are expected to comply immediately.<br />
<br />
Contributors to the GitHub repository, the Meetup and/or event-related sites, sponsors, or similar are also subject to the anti-harassment policy. Organizers (including volunteers) should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Budapest_Hackathon_2017&diff=62022Budapest Hackathon 20172017-07-27T12:08:57Z<p>Heisenbug: suggest "STG Optimisations"</p>
<hr />
<div>[[File:Bp hh 2017.png|768px]]<br />
<br />
[[File:Budapest01.jpg|300px|right]]<br />
[[File:BudapestPub01.jpg|300px|right]]<br />
[[File:BudapestPub02.jpg|300px|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|2017July 29 - 30th (Saturday & Sunday)<br />
|-<br />
|Hours:<br />
|09:00 ~ 17:00<br />
|-<br />
|Where:<br />
|[https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media Hungary, 1062 Andrássy út 66.]<br />
|}<br />
----<br />
<br />
<br />
== About ==<br />
<br />
[https://meetup.com/Bp-HUG/ The Budapest Haskell User Group] will once again hold a two day Haskell Hackathon in Budapest. This is the third the occasion (info about [https://wiki.haskell.org/BudapestHackathon2014 the first], [https://wiki.haskell.org/Budapest_Hackathon_2016 and second hackathon]), and this time we will hold it in Gizmodo Media Group's Budapest office.<br />
The event is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure, and growing the local community.<br />
<br />
This is a great opportunity to meet your fellow Haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones!<br />
<br />
This event is open to any experience level, from beginners to gurus. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community. We will have a dedicated beginners' track, and there are going to be experienced haskellers on site whom you can directly approach during the whole event with any Haskell-related question that might pop up.<br />
<br />
There will be lots of hacking, good food, and, of course, fun!<br />
<br />
<p><br />
<br />
== Sponsors ==<br />
<br />
[[File:Gmg logo.png|center|200px]]<br />
[[File:Digital asset logo.png|center|400px]]<br />
[[File:Iseeq logo.png|center|250px]]<br />
<br />
Many thanks to [http://gizmodo.com/careers/budapest#openings GMG] for hosting, and [https://digitalasset.com Digital Asset], and [http://iseeq.co IseeQ] for sponsoring the event.<br />
<br />
== Registration ==<br />
<br />
You can fill out the necessary registration information [https://goo.gl/forms/QjTNdXTD1aEOMEQU2 here]. <br/>There is no registration deadline, or requirement really, so you can join us even if you didn't fill out the form, it just help us with the organization.<br />
<br />
== Venue ==<br />
<br />
[[File:a66_front.jpg|300px|right]]<br />
[[File:a66_inside_1.jpg|300px|right]]<br />
[[File:a66_inside_2.jpg|300px|right]]<br />
<br />
The Hackathon will be held at [https://goo.gl/maps/BPa5qRU2aPz Gizmodo Media's Budapest office]. WiFi, projectors for talks, and snacks & refreshments will be provided by our sponsors.<br/><br />
Detailed schedules will be posted soon.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Budapest ===<br />
You can find out more about [http://www.budapest.com/ Budapest] on [http://wikitravel.org/en/Budapest these] [https://www.tripadvisor.com/Tourism-g274887-Budapest_Central_Hungary-Vacations.html sites]. Travel informations can be found on [http://bud.hu/english bud.hu].<br />
<br />
==== By Plane ====<br />
<br />
From [https://www.google.com/maps/place/Budapest+Airport/@47.4183176,19.2539053,13z/data=!4m2!3m1!1s0x4741c1a4fe39860b:0x4ca4f6a650439aa1 Liszt Ferenc Airport] by public transport: [http://bud.hu/english/passengers/access_and_parking/by_public_transportation 200E Bus] and [http://www.bkk.hu/en/timetables/#M3 M3 (Metro line 3 or blue line)].<br />
<br />
=== Getting to the venue ===<br />
<br />
The Gizmodo Media Group's offices ([https://www.google.com/maps/d/viewer?mid=1AyxcMMg-WojQnb7b9OMdkqu-QeU&hl=en 1062 Budapest, Andrássy út 66.]) are near center of the city, so it can be easily approached even by foot from downtown accommodations.<br />
For public transport timetables, and more informations please visit the local transport authority’s [http://www.bkk.hu/en/main-page/news/ site].<br />
<br/><br />
'''Information about tickets, and recommended tickets:'''<br />
<br />
* [http://www.bkk.hu/en/prices/ Local Transport Tikets and Passes]<br />
* [http://www.bkk.hu/en/block-of-10-tickets/ Block of 10 tickets]<br />
* [http://www.bkk.hu/en/budapest-72-hour-travel-card/ Budapest 72-hour travel card]<br />
<br />
'''Local Taxis''':<br />
* [http://bud.hu/english/passengers/access_and_parking/by_taxi Airport Taxi Information]<br />
* [http://www.tripadvisor.com/Travel-g274887-c167515/Budapest:Hungary:A.Tip.Budapest.Taxi.Fares.And.Advice.html Budapest taxi information (tripadvisor.com)]<br />
* [http://www.budapest.com/travel/getting_around/taxi.en.html List of Taxi companies]<br />
<br />
=== Accommodation ===<br />
<br />
* [http://www.k9residence.com/ K9 Residence] (In the city center, from 40 euro/night)<br />
* [https://www.airbnb.com/s/Budapest--Hungary/homes?allow_override%5B%5D=&checkin=2017-07-23&checkout=2017-07-31 Airbnb]<br />
* [http://www.only-apartments.com/apartments-budapest.html OnlyApartments.com]<br />
* [http://www.holidaylettings.co.uk/budapest/ HolidayLettings]<br />
* [http://www.bbhostel.hu/ Budapest Budget Hostel]<br />
* [http://www.hostelworld.com/search?search_keywords=Budapest%2C+Hungary&country=Hungary&city=Budapest&date_from=2014-05-30&date_to=2014-06-02 HostelWorld]<br />
<br />
== Schedule ==<br />
<br />
''Note:'' This is only an approximate schedule.<br />
<br />
{| class="wikitable"<br />
|-<br />
! !! Saturday !! Sunday<br />
|-<br />
| 9:00 || doors open || doors open<br />
|-<br />
| 9:30 || ''Andres Löh'' <br/> '''generics-sop''' || ''András Leitereg, Dániel Berényi'' <br/> '''LambdaGen: A GPU Code Generator Powered by Recursion Schemes'''<br />
|-<br />
| 10:10 || short break || short break<br />
|-<br />
| 10:20 || ''Michal Kawalec'' <br/> '''Functional programming with bananas in barbed wire''' || '''Lightning talks'''<br />
|-<br />
| 11:00 || project discussions, start of project work || project discussions, start of project work<br />
|-<br />
| 13:30 || lunch break || lunch break<br />
|-<br />
| 16:30 || || demo session<br />
|-<br />
| 17:00 || end of scheduled programs, beers || end of scheduled programs, beers<br />
|}<br />
<br />
== Projects ==<br />
<br />
=== generics-sop: Generic Programming using True Sums of Products ===<br />
<br />
'''Description'''<br />
<br />
generics-sop is a library for datatype-generic programming in Haskell. <br />
Datatypes are viewed as n-ary sums of n-ary products. Such sums and <br />
products are represented in a type-safe way using Haskell GADTs and <br />
manipulated via higher-rank polymorphic combinators provided by the <br />
library. <br />
<br />
The core of the library is relatively stable, but some new features, <br />
such as type-level metadata, require more experience to stabilize. <br />
So one open task is to just experiment with type-level metadata and <br />
provide feedback. <br />
<br />
Other tasks are improving the documentation, and creating a systematic <br />
benchmark suite so that the performance of generics-sop can be measured <br />
and the performance of different existing internal representations can <br />
be compared with each other. <br />
<br />
'''Contact''': Andres Löh<br />
<br />
'''Homepage''': https://github.com/well-typed/generics-sop<br />
<br />
=== hs-di ===<br />
<br />
'''Description''': Dependency Injection library for Haskell to allow powerful unit testing and mocking (compile-time type-checked)<br />
<br />
'''Contact''': Milan Nagy<br />
<br />
'''Homepage''': https://hackage.haskell.org/package/hs-di<br />
<br />
=== STG Optimisations ===<br />
<br />
'''Description''': Since the GHC's internal STG language is unityped, the runtime representation of `\case Right a -> Just a` is the identity (`id`) operationally. However, this optimisation currently is not implemented. Something similar is already done, so this might be low-hanging fruit.<br />
<br />
'''Contact''': Gabor Greif<br />
<br />
'''Homepage''': https://ghc.haskell.org/trac/ghc/ticket/13861<br />
<br />
== Talks/demos ==<br />
<br />
As of yet the following talks are scheduled:<br/><br />
<br />
=== Andres Löh - generics-sop ===<br />
<br />
'''Abstract'''<br />
<br />
Datatype-generic programming and generics-sop provides access to the <br />
internal structure of datatype definitions, allowing functions to <br />
access datatype constructors and their arguments in a uniform yet <br />
type-safe way. As a result, we can implement functions that work over <br />
a large range of datatypes and are typically built into the compiler <br />
as "derivable" classes directly within Haskell, such as equality and <br />
comparison functions, (de)serialization functions to various formats, <br />
or generic traversals such as maps and folds. <br />
<br />
We will look at a number of examples and show how they can be solved <br />
with generics-sop.<br />
<br />
'''Talk/Project repo'''<br />
<br />
https://hackage.haskell.org/package/generics-sop<br />
<br />
'''Presenter'''<br />
<br />
Andres is a partner and Haskell Consultant at [http://www.well-typed.com Well-Typed LLP].<br />
<br />
=== András Leitereg, Dániel Berényi - LambdaGen: A GPU Code Generator Powered by Recursion Schemes ===<br />
<br />
'''Abstract'''<br />
<br />
Problems that are data and computation intensive but are also naturally parallelizable are very frequent in physics, statistics and other fields of science. Their efficient parallel implementation would however require not just decent programming skills, but also deep insight of the target architecture. These computations are often in the form of a linear algebraic expression, and our goal is to deduce their optimal parallelization and memory usage automatically. We'd like to create a tool that offers a compromise between minimizing the implementation and the running time, for scientists who are not programmers.<br />
We chose a small set of high level operations accessible through a Haskell EDSL, with which the users build an expression tree of their computation. Then we apply a series of recursion scheme based transformations on the expression tree, and finally produce a [https://www.khronos.org/sycl SYCL] source code to evaluate the expression on GPU. We keep this abstract representation throughout the processing, which opens the possibility of optimizations that are otherwise difficult to recognize and carry out. It also minimizes the time we spent with debugging, but imposes some problems that are specific to the functional context.<br />
<br />
'''Talk/Project repo'''<br />
<br />
* https://github.com/leanil/LambdaGen<br />
<br />
'''Presenters'''<br />
<br />
* András Leitereg (Department of Informatics, Eötvös Loránd University)<br />
* Dániel Berényi (Wigner GPU Lab)<br />
<br />
=== Michal Kawalec - Functional programming with bananas in barbed wire ===<br />
<br />
''' Proposal '''<br />
<br />
In our day to day functional programming, we encounter recursion every<br />
step of the way. If only there were a way of abstracting away its<br />
repetitive parts and clarifying the recursive code with minimal<br />
boilerplate!<br />
<br />
Fortunately, recursion schemes come to the rescue. They allow for a<br />
clear and concise definition of recursion, while being guided by the<br />
typechecker. The talk will present basic theory behind them but will not<br />
require advanced knowledge of mathematics. We believe that recursion<br />
schemes can greatly benefit from a more widespread usage and will try to<br />
convey the practical ways in which they can be used in real life<br />
programs.<br />
<br />
''' Bio '''<br />
<br />
Michal is an engineer of many trades. He is currently responsible for<br />
libraries and architecture of League of Legends, and, previously, he had worked<br />
with startups, supercomputers, and particle detectors. At night, he<br />
writes Haskell libraries and runs the biggest Haskell Meetup in Poland.<br />
<br />
=== Notes regarding the talks ===<br />
<br />
We plan more, and we will update this site regularly so check back later.<br />
<br />
Apart from longer presentations, it will be possible to give lightning talks, or project demos. If you're interested in giving one of these, please contact us on one of the addresses at the bottom of the page.<br />
<br />
== Attendees ==<br />
<br />
Here is the [[/Attendees|list of participants]] who have signed up, and have chosen their name to be listed.<br />
<br />
== Communication ==<br />
<br />
If you have any questions about the event you can reach us here:<br />
<br />
* E-mail: [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
* Twitter: [http://twitter.com/bp_hug @bp_hug]<br />
* Gitter: [https://gitter.im/BP-HUG BP-HUG]<br />
* Meetup: [http://meetup.com/Bp-HUG/ Budapest Haskell User Group]<br />
<br />
All code from this and past event will be uploaded to the meetup’s [https://github.com/BP-HUG/ Github page].<br />
<br />
== Organizers ==<br />
<br />
* Dániel Berecz<br />
* Csaba Hruska<br />
* Péter Diviánszky<br />
* Andor Pénzes<br />
<br />
== Code of Conduct ==<br />
<br />
All attendees, speakers, exhibitors, organizers, contributors and volunteers are required to conform to the following Code of Conduct.<br />
<br />
BP-HUG events are for anyone interested in the Haskell language, its history, related topics, and want to discuss them in a fun, engaging and respectful environment.<br />
<br />
'''Be an adult, don't be a jerk.'''<br />
<br />
We value the participation of each member of the community and want all attendees to have an enjoyable and fulfilling experience. Accordingly, all attendees are expected to show respect and courtesy to other attendees throughout the meet-ups, this hackathon, and on the electronic channels listed above.<br />
<br />
=== Need help? ===<br />
<br />
If you are experiencing harassment on or have concerns about the content please contact:<br />
<br />
* '''Dániel Berecz:''' dαniεl.bεrεcz@gmαil.com (replace the greek letters)<br />
* '''All:''' [mailto:budapest.hug@gmail.com budapest.hug@gmail.com]<br />
<br />
The organizers will be available to help you with any issues or concerns at this event.<br />
<br />
=== What it means ===<br />
<br />
The BP-HUG is dedicated to providing a harassment-free experience for everyone, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of meet-up participants in any form.<br />
<br />
All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate for any meet-up, including talks.<br />
<br />
Be kind to others. Do not insult or put down other attendees. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for this event.<br />
<br />
Attendees violating these rules may be asked to leave the meet-up at the sole discretion of the organizers.<br />
<br />
Thank you for helping make this a welcoming, friendly event for all.<br />
<br />
=== Spelling it out ===<br />
<br />
Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, religion, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.<br />
<br />
Participants asked to stop any harassing behavior are expected to comply immediately.<br />
<br />
Contributors to the GitHub repository, the Meetup and/or event-related sites, sponsors, or similar are also subject to the anti-harassment policy. Organizers (including volunteers) should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Monoid&diff=61963Monoid2017-07-05T06:36:22Z<p>Heisenbug: Fixed Product monoid</p>
<hr />
<div>In Haskell, the Monoid typeclass (not to be confused with [[Monad]]) is a class for types which have a single most natural operation for combining values, together with a value which doesn't do anything when you combine it with others (this is called the ''identity'' element). It is closely related to the [[Foldable]] class, and indeed you can think of a Monoid instance declaration for a type ''m'' as precisely what you need in order to fold up a list of values of ''m''.<br />
<br />
== The basics ==<br />
<br />
=== Declaration ===<br />
<br />
<haskell><br />
class Monoid m where<br />
mempty :: m<br />
mappend :: m -> m -> m<br />
mconcat :: [m] -> m<br />
-- defining mconcat is optional, since it has the following default:<br />
mconcat = foldr mappend mempty<br />
<br />
-- this infix synonym for mappend is found in Data.Monoid<br />
x <> y = mappend x y<br />
infixr 6 <><br />
</haskell><br />
<br />
together with the following laws:<br />
<br />
<haskell><br />
-- Identity laws<br />
x <> mempty = x<br />
mempty <> x = x<br />
<br />
-- Associativity<br />
(x <> y) <> z = x <> (y <> z)<br />
</haskell><br />
<br />
=== Examples ===<br />
<br />
The prototypical and perhaps most important example is lists, which form a monoid under concatenation:<br />
<br />
<haskell><br />
instance Monoid [a] where<br />
mempty = []<br />
mappend x y = x ++ y<br />
mconcat = concat<br />
</haskell><br />
<br />
Indeed, appending the empty list to either end of an existing list does nothing, and <hask>(x ++ y) ++ z</hask> and <hask>x ++ (y ++ z)</hask> are both the same list, namely all the elements of <hask>x</hask>, then all the elements of <hask>y</hask>, them all the elements of <hask>z</hask>.<br />
<br />
Numbers also form a monoid under addition, with 0 the identity element, but they also form a monoid under multiplication, with 1 the identity element. Neither of these instances are really more natural than the other, so we use the [[newtype]]s <tt>Sum n</tt> and <tt>Product n</tt> to distinguish between them:<br />
<br />
<haskell><br />
newtype Sum n = Sum n<br />
<br />
instance Num n => Monoid (Sum n) where<br />
mempty = Sum 0<br />
mappend (Sum x) (Sum y) = Sum (x + y)<br />
<br />
newtype Product n = Product n<br />
<br />
instance Num n => Monoid (Product n) where<br />
mempty = Product 1<br />
mappend (Product x) (Product y) = Product (x * y)<br />
</haskell><br />
<br />
Now <hask>mconcat</hask> on a list of <hask>Sum Integer</hask> (say) values works like <hask>sum</hask>, while on a list of <hask>Product Double</hask> values it works like <hask>product</hask>.<br />
<br />
=== So what? ===<br />
<br />
There are several reasons why you want a typeclass for combining things, e.g. because it couples well with other typeclasses (the aforementioned [[Foldable]], or the [[Writer monad]], or some [[Applicative]]s). But for a rather striking example of what Monoid can do alone, you can look at the way its instances can work together. First, <hask>Ordering</hask>, the standard type which Haskell uses for the result of <hask>compare</hask> functions, has a "lexicographic" combination operation, where <hask>mappend</hask> essentially takes the first non-equality result. Secondly, if <hask>b</hask> is a Monoid, then functions of type <hask>a -> b</hask> can be combined by just calling them both and combining the results. Now, of course, since <hask>a -> a -> b</hask> is just a function returning a function, it can also be combined in the same way, and so you can combine comparison functions, of type <hask>a -> a -> Ordering</hask>, and write the following sorts of thing, which means "sort strings by length and then alphabetically":<br />
<br />
<haskell><br />
sortStrings = sortBy (comparing length <> compare)<br />
</haskell><br />
<br />
Isn't that wonderfully descriptive? And we didn't write any functions specifically to do this – it's just composed of simple, reusable parts.<br />
<br />
== In more depth ==<br />
<br />
=== On mconcat ===<br />
<br />
mconcat is often presented as just an optimisation, only in the class so that people can define more efficient versions of it. That's true in a sense, but note that mempty and mappend can just as well be defined in terms of mconcat:<br />
<br />
<haskell><br />
mempty = mconcat []<br />
mappend x y = mconcat [x, y]<br />
</haskell><br />
<br />
What of the laws? Well, we can have the following:<br />
<br />
<haskell><br />
mconcat [x] = x<br />
mconcat (map mconcat xss) = mconcat (concat xss)<br />
</haskell><br />
<br />
The first rule is natural enough. The second rule is a little more subtle, but basically says that if you have a list of lists of some monoidy things, and you mconcat each sublist individually, then mconcat all the results, that's just the same as if you had squashed all the sublists together first, and mconcatted the result of that. Or in other words, it's telling you something like what associativity tells you, that the order in which you fold up a list doesn't matter.<br />
<br />
==== Categorical diversion ====<br />
<br />
Note that the above two laws can also be phrased as follows:<br />
<br />
<haskell><br />
mconcat . return = id<br />
mconcat . map mconcat = mconcat . join<br />
</haskell><br />
<br />
In [[category theory]] terms, this is exactly the condition for <hask>mconcat</hask> to be a monad algebra for the list monad.<br />
<br />
=== On the Writer monad ===<br />
<br />
The [[Writer monad]] is a way to put a monad structure on tuples. You write bind like this:<br />
<br />
<haskell><br />
(w,x) >>= f =<br />
case f x of<br />
(v, y) -> (w <> v, y)<br />
</haskell><br />
<br />
Notice that it's the monoid instance of the first component that allows you to incorporate both <tt>w</tt> and <tt>v</tt> into the final result, which seems like an important thing to do.<br />
<br />
You might, however, wonder if there's not some other way to get a law-abiding monad. The answer is essentially no: if <hask>(w,a)</hask> is a monad, you can use its monad instance to write a monoid instance for <hask>w</hask>: basically <hask>mempty = fst (return ())</hask> and <hask>mappend x y = fst (join (x,(y,()))</hask>, and the monad laws ensure associativity and identity. So in fact, monoids are exactly what you need to make a monad structure on tuples.<br />
<br />
=== On the Const applicative ===<br />
<br />
Even more straightforwardly, <hask>Const m</hask> is applicative precisely when <hask>m</hask> is a monoid.<br />
<br />
== See also ==<br />
<br />
* [http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html Haskell Monoids and their Uses]<br />
* [http://apfelmus.nfshost.com/monoid-fingertree.html Monoids and Finger Trees]<br />
* [http://haskell.org/sitewiki/images/6/6a/TMR-Issue11.pdf Monad.Reader issue 11, "How to Refold a Map."] (PDF), and a [http://haskell.org/haskellwiki/The_Monad.Reader/Discuss_Issue11 follow up]<br />
<br />
Generalizations of monoids feature in [[Category theory]], for example:<br />
* [http://www.researchgate.net/publication/235540658_Arrows_like_Monads_are_Monoids/file/d912f511ccdf2c1016.pdf Arrows, like Monads, are Monoids] (PDF)</div>Heisenbughttps://wiki.haskell.org/index.php?title=Section_of_an_infix_operator&diff=61678Section of an infix operator2017-03-31T17:58:50Z<p>Heisenbug: </p>
<hr />
<div>In Haskell there is a special syntax for [[partial application]] on [[infix operator]]s. Essentially, you only give one of the arguments to the infix operator, and it represents a function which intuitively takes an argument and puts it on the "missing" side of the infix operator.<br />
<br />
* <hask>(2^)</hask> (left section) is equivalent to <hask>(^) 2</hask>, or more verbosely <hask>\x -> 2 ^ x</hask><br />
* <hask>(^2)</hask> (right section) is equivalent to <hask>flip (^) 2</hask>, or more verbosely <hask>\x -> x ^ 2</hask><br />
<br />
<br />
Like [[partial application]] and [[lambda abstraction]], sectioning provides a convenient way of writing some functions without having to explicitly name them:<br />
* <hask>(1+)</hask> (unsugared: <hask>(+) 1</hask>) is the "increment" function,<br />
* <hask>(2*)</hask> is the "double" function, <br />
* <hask>('\t':)</hask> is the "indent" function, <br />
* <hask>(`elem` "AEIOU")</hask> is the "is-capital-vowel-in-English" function (ignoring the "sometimes Y"). <br />
<br />
Note: as an exception, the "-" (subtraction) operator cannot do a right section, because that would be interpreted as unary negation in Haskell syntax. The Prelude function "subtract" is provided for this purpose. Instead of <hask>(- e)</hask>, you need to write <hask>(subtract e)</hask>.<br />
<br><br />
Note: Iterated sections are also possible, as long the associativity is correct: <hask>(1+2+)</hask>. The famous (but mostly useless) "Bender" operator is <hask>(:8:[])</hask>.<br />
<br />
== See also ==<br />
<br />
* [[Currying]]<br />
* [http://www.haskell.org/onlinereport/exps.html#sections Haskell report: Sections] - see for more details<br />
<br />
[[Category:Glossary]]<br />
[[Category:Syntax]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Section_of_an_infix_operator&diff=61677Section of an infix operator2017-03-31T17:56:18Z<p>Heisenbug: Iterated</p>
<hr />
<div>In Haskell there is a special syntax for [[partial application]] on [[infix operator]]s. Essentially, you only give one of the arguments to the infix operator, and it represents a function which intuitively takes an argument and puts it on the "missing" side of the infix operator.<br />
<br />
* <hask>(2^)</hask> (left section) is equivalent to <hask>(^) 2</hask>, or more verbosely <hask>\x -> 2 ^ x</hask><br />
* <hask>(^2)</hask> (right section) is equivalent to <hask>flip (^) 2</hask>, or more verbosely <hask>\x -> x ^ 2</hask><br />
<br />
<br />
Like [[partial application]] and [[lambda abstraction]], sectioning provides a convenient way of writing some functions without having to explicitly name them:<br />
* <hask>(1+)</hask> (unsugared: <hask>(+) 1</hask>) is the "increment" function,<br />
* <hask>(2*)</hask> is the "double" function, <br />
* <hask>('\t':)</hask> is the "indent" function, <br />
* <hask>(`elem` "AEIOU")</hask> is the "is-capital-vowel-in-English" function (ignoring the "sometimes Y"). <br />
<br />
Note: as an exception, the "-" (subtraction) operator cannot do a right section, because that would be interpreted as unary negation in Haskell syntax. The Prelude function "subtract" is provided for this purpose. Instead of <hask>(- e)</hask>, you need to write <hask>(subtract e)</hask>.<br />
<br />
Note: Iterated sections are also possible, as long the associativity is correct: <hask>(1+2+)</hask>. The famous (but mostly useless) "Bender" operator is <hask>(:8:[])</hask>.<br />
<br />
== See also ==<br />
<br />
* [[Currying]]<br />
* [http://www.haskell.org/onlinereport/exps.html#sections Haskell report: Sections] - see for more details<br />
<br />
[[Category:Glossary]]<br />
[[Category:Syntax]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=User_groups&diff=60858User groups2016-06-30T07:24:23Z<p>Heisenbug: /* Germany */ added Regensburg</p>
<hr />
<div>[[Category:Community]]<br />
<br />
A range of Haskell User Groups are springing up all over.<br />
<br />
== Online communities ==<br />
* [http://www.reddit.com/r/haskell/ Haskell Reddit]<br />
* [http://stackoverflow.com/questions/tagged?tagnames=haskell Haskell on Stack Overflow]<br />
<br />
== User groups ==<br />
<br />
Regular meetings in a particular geographical area. Great if you want to see and meet other Haskellers.<br />
<br />
<br />
===Africa===<br />
<br />
====South Africa====<br />
; [http://www.meetup.com/lambda-luminaries/ Lambda Luminaries] : Functional programming user group based in Centurion, Gauteng.<br />
<br />
===Asia===<br />
<br />
====China====<br />
;[http://lisp.org.cn/en/ China Lisp User Group]<br />
:China Lisp User Group (CLUG) is the earliest founded Lisp user group in China. <br />
<br />
====Hong Kong====<br />
;[http://www.meetup.com/HK-Functional-programming/ Hong Kong Functional Programming User Meetup Group]<br />
<br />
====Japan====<br />
;[http://www.starling-software.com/en/tsac.html Tokyo Society for the Application of Currying]<br />
<br />
;[http://www.meetup.com/Tokyo-Haskell-Meetup/ Tokyo Haskell Meetup]<br />
:Casual monthly meetings to help each other learn Haskell<br />
<br />
===Europe===<br />
<br />
==== Belgium ====<br />
<br />
;[[Ghent Functional Programming Group]]<br />
:The Ghent Functional Programming Group will be having its first meeting on April 1, 2010.<br />
<br />
;[https://groups.google.com/forum/#!forum/leuven-haskell Leuven Haskell User Group]<br />
:The Leuven Haskell User Group was launched on March 3, 2015 and meets every two weeks.<br />
<br />
==== France ====<br />
<br />
;[[Fr/Haskell]]<br />
:The Strasbourg HUG meets monthly in an informal setting. Level is very low and newbies are very welcome.<br />
<br />
==== Germany ====<br />
<br />
;Curry Club Augsburg<br />
:http://curry-club-augsburg.de/<br />
<br />
;Berlin HUG<br />
:http://www.meetup.com/berlinhug/<br />
<br />
;Haskell in Frankfurt<br />
: <ul><li>[http://www.meetup.com/Frankfurt-Haskell-User-Group Frankfurt Haskell User Group] meets monthly.</li><li> [http://wiki.lug-frankfurt.de/Programmierworkshop/aktuell Regular Saturday Workshop] taking place every couple of months. Feel free to join us!</li><br />
<br />
;[http://www.iba-cg.de/hal5.html Haskell in Leipzig]<br />
:Hal, they have videos [http://iba-cg.de/haskell.html online].<br />
<br />
;[http://www.haskell-munich.de Haskell in Munich]<br />
: We had our first meeting on Thursday, 29th of September 2011. We are always looking forward to see new people. If you can make it to Munich, consider joing us!<br />
<br />
;[http://www.meetup.com/de-DE/Regensburg-Haskell-Meetup Regensburg Haskell Meetup]<br />
: We meet regularly once a month since 2014. Folks from the Munich and Nuremberg area frequently join.<br />
<br />
;Interest for User Groups in Germany<br />
* '''Ulm''': [[HugUlm]]<br />
* '''Mannheim or Heidelberg''': [[User:Cgo|cgo]] ([http://www.haskell.org/haskellwiki/?title=Special:Emailuser&target=Cgo mail]), [[User:HC|hc]]<br />
<br />
==== Greece ====<br />
<br />
;[https://groups.google.com/forum/#!forum/haskell-greece/ Haskell Greece Google group]<br />
<br />
==== Hungary ====<br />
<br />
;[http://www.meetup.com/Bp-HUG Budapest Haskell User Group]<br />
:The Haskell User Group is a group of Haskell enthusiasts who are interested in sharing their knowledge and meeting people who share similar interests. We had our first meeting in September 2013.<br />
<br />
==== Iceland ====<br />
<br />
;[[Reykjavik Haskell User Group]] Iceland<br />
;[http://groups.google.com/group/haskell-is Currently recruiting members]<br />
<br />
==== Israel ====<br />
<br />
;[[IsraelHaskell]] User Group<br />
:[http://article.gmane.org/gmane.comp.lang.haskell.cafe/28877 Are getting organised].<br />
* '''Konstanz''': [[User:Thkoch|thkoch]]<br />
<br />
==== Italy ====<br />
;[[ItaloHaskell]]<br />
:We had a first meeting in August 2008 and we are planning a second one sometime during the 2008/2009 Autumn/Winter season.<br />
<br />
==== Netherlands ====<br />
<br />
;[http://dutchhug.nl/ Dutch HUG]<br />
:The Dutch HUG meets monthly in an informal setting.<br />
<br />
==== Norway ====<br />
<br />
;[http://www.meetup.com/Oslo-Haskell/ Osλo Haskell]<br />
:Osλo Haskell is a group for Haskellers and people interested in Haskell and related languages in and around Oslo. We had our first meeting in March 2014.<br />
<br />
;[http://www.meetup.com/Trondheim-Haskell-Users-Group/ Trondheim Haskell Users' Group]<br />
:A Haskell users' group in the Trondheim area. For seasoned veterans, complete newbies who only heard of Haskell two minutes ago, and everyone in between and beyond. We meet and talk about Haskell and anything else members are interested in.<br />
<br />
==== Poland ====<br />
;[https://plus.google.com/u/0/communities/103183708602453146804 HUG Warsaw] <br />
We are the successors to the Warsaw Functional Society (Warszawskie Towarzystwo Funkcyjne) and as such we welcome any functional programmers and enthusiasts, though the focus of the group is Haskell. We (hope to) have rather informal, but regular meetings in Warsaw, Poland.<br />
<br />
==== Russia ====<br />
<br />
;[http://ruhaskell.org/ Russian community of Haskell-developers]<br />
;[http://spbhug.folding-maps.org Saint-Petersburg Haskell User Group]<br />
;[https://groups.google.com/forum/#!forum/mskhug Moscow Haskell User Group]<br />
;[https://groups.google.com/forum/#!aboutgroup/haskell-russian haskell-russian mailing list]<br />
<br />
==== Switzerland ====<br />
<br />
;[http://www.meetup.com/HaskellerZ/ Haskell User Group Zurich]<br />
:We are meeting once a month to share knowledge of and experience with Haskell.<br />
<br />
;[http://www.meetup.com/Geneva-Haskell-Group/ Geneva Haskell Group]<br />
:We are a Haskell community in Geneva planning to meet up every week.<br />
<br />
==== Turkey ====<br />
<br />
;[http://groups.google.com/group/core-haskell?lnk=srg Turkey Haskell Programmer's Group]<br />
:Formed by Turkish Functional Programmers, the group began to communicate via an e-mail list opened by core.gen.tr. The first contribution is hlibev project by Aycan iRiCAN.<br />
<br />
;[http://bilfp.wikidot.com/ BILFP (Bilkent University Comp. Eng. Dept. Functional Programming Society)] Turkey <br />
:Project aims to improve people's knowledge and encourage the use of functional programming languages &mdash; especially in Turkey. Group is open to functional-programming-related discussions and establishes related presentations at Bilkent University that are open to anybody.<br />
<br />
==== UK ====<br />
;[http://lambdalounge.org.uk/ Manchester Lambda Lounge]<br />
:We are an active community meeting monthly at the [http://madlab.org.uk/ Madlab] (Manchester Digital Laboratory) to talk about topics in functional programming.<br />
<br />
;[http://www.meetup.com/hoodlums/ Hoodlums - Haskell developer meetup]<br />
:Meets monthly on the second Thursday of the month in Canary Wharf. It is a "Coding Dojo" format where we pick some interesting problem and solve it as a group. <br />
<br />
;[http://www.meetup.com/London-HUG/ London Haskell User Group]<br />
:The main meetings are monthly on the last or fourth Thursday of the month. The group was revived in late 2012.<br />
<br />
;[http://www.meetup.com/ed-lambda/ ed lambda (Edinburgh, UK)]<br />
:For functional programming in general, founded by a Haskeller. First meeting will be September 13th 2010.<br />
<br />
;[http://groups.google.com/group/oxhug OxHUG - the Oxford Haskell Users Group]<br />
:Meets every other week, currently at the Department of Computer Science, University of Oxford. Discussion session followed by adjournment to a local tavern. Aimed at students, graduates, professionals and enthusiasts.<br />
<br />
;[http://groups.google.com/group/fp-southwales fp-southwales], the South Wales Functional Programming User Group<br />
:Starting up in late 2009, based out of Swansea University.<br />
<br />
==== Ukraine ====<br />
;[https://groups.google.com/forum/#!forum/ltu-kiev LtU-Kiev community]<br />
:Irregular meetups, usually with prepared talks on Haskell and other FP topics.<br />
;[http://ro-che.info/odhug Odessa Haskell User Group]<br />
:Regular informal meetups (approximately once a month) in a pub or cafe<br />
<br />
===North America===<br />
<br />
====Central====<br />
<br />
;[http://leibnizdream.wordpress.com/2007/12/22/new-austin-functional-programmers-group-in-2008/ Austin Functional Programmers Group]<br />
:See the [http://groups.google.com/group/austin-fp discussion group] for more.<br />
<br />
;[http://www.meetup.com/Boulder-Haskell-Programmers/ Boulder Haskell Programmers]<br />
: Boulder and Denver (Colorado) area Haskell Programmer Group. Meetings are focused on practical topics faced by working programmers. All experience levels are welcome.<br />
<br />
;[http://groups.google.com/group/real-world-haskell-book-club/browse_thread/thread/3e8e59768c8c50a9 Colorado Area Haskell Study Group]<br />
<br />
;[http://ChicagoHaskell.com Chicago Haskell] — First general meeting in December 2009. — [https://groups.google.com/forum/#!forum/haskell-chicago Mailing List] — [https://twitter.com/ChicagoHaskell @ChicagoHaskell]<br />
<br />
;[http://www.meetup.com/DenHUG/ Denver Area Haskell Users Group] -- DenHUG had it's first meeting on 27 Feb 2010. Next meeting will be 3 Apr 2010.<br />
<br />
;[http://www.meetup.com/Houston-Haskell-Users-Group/ Houston Haskell Users Group] -- Meets the 1st Monday of every month at [https://txrxlabs.org/ TxRx labs]<br />
<br />
;[http://www.lambdalounge.org St. Louis Lambda Lounge] -- Meets the 1st Thursday of the month. Since Dec 2008, Lambda Lounge is a user group in St. Louis organized loosely around the idea of exploring dynamic and functional languages.<br />
<br />
;[http://www.meetup.com/Nashville-Haskell-Users-Group Nashville Haskell Users Group (NHUG)] -- Meets 1st Tuesday of each month.<br />
<br />
====East Coast====<br />
<br />
;[http://groups.google.com/group/bostonhaskell Boston Haskell Users' Group].<br />
:Meets monthly.<br />
<br />
;[http://www.meetup.com/NY-Haskell/ New York Haskell Users Group]<br />
:The NY Haskell Users Group is for all programmers either interested in or experienced with the Haskell programming language. Meets monthly.<br />
<br />
;[http://www.meetup.com/lisp-59/ New York Functional Programmers]<br />
:Come and meet like-minded functional programmers in the New York area.<br />
<br />
;[http://www.meetup.com/Haskell-DC/ Haskell DC]<br />
:Washington DC area Meetup for Haskell.<br />
<br />
;[http://www.lisperati.com/fringedc.html FringeDC Washington]<br />
:Meetings about functional programming languages in Washington DC.<br />
<br />
;[http://groups.google.com/group/AFPUG Atlanta Functional Programming Users Group]<br />
:Meet other functional programmers in the Atlanta area. Join us and geek out!<br />
<br />
;Toronto Haskell User Group<br />
:Haskellers of Toronto, unite! We meet at [https://bentomiso.com/events Bento Miso] on the second Wednesday of every month (check the [https://bentomiso.com/events event page] to be sure; it's usually up-to-date). There is also a small organizational [http://groups.google.com/group/toronto-haskell/ mailing list] you can join to keep up to date.<br />
<br />
;[http://www.haskellers-montreal.com/ Haskellers Montreal Group].<br />
:Meets every 2 months on the first Wednesday of that month, currently at Centre [http://cloud.ca Cloud.ca] (previously known as RPM). Talks alternate from expert-level to more newcomer-oriented ones; and we organize through our [http://haskell-meetup.sandreckoning.com/ website], a [https://groups.google.com/forum/#!forum/haskellers-montreal Google group] and a [http://www.meetup.com/Haskellers-Montreal-Meetup/ meetup.com] page.<br />
<br />
====West Coast ====<br />
<br />
;[http://socalfp.blogspot.com/ SoCal FP Group]<br />
<br />
;[http://www.meetup.com/sandiegohug/ San Diego Haskell User Group]<br />
:a Haskell User Group for the San Diego and Tijuana region<br />
<br />
;[http://bayfp.org/ The Bay Area Functional Programmers group]<br />
:Meeting monthly in the San Francisco Bay area. See [http://bayfp.org/blog their blog] for more details and news of upcoming meetings.<br />
<br />
;[http://pdxfunc.org PDXfunc: Portland FP Group]<br />
:Monthly meetings of the Portland, Oregon functional programming group. Meetings occur on the second Monday of each month at 7 pm, typically in Downtown/NW Portland.<br />
<br />
;[http://seattlehaskell.org/ Seattle Area Haskell Users' Group]<br />
:Monthly get-togethers serving Seattle and the Eastside (see also [http://meetup.com/SEAHUG/ Meetup.com] for details)<br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2008-February/038991.html Seattle: Northwest Functional Programming Interest Group]<br />
:a Northwest Functional Programming Interest Group in Seattle.<br />
<br />
;[http://www.meetup.com/Vancouver-Haskell-Unmeetup/ Vancouver Haskell UnMeetup]<br />
:Monthly interactive sessions, (+10) for joining<br />
<br />
===Oceania===<br />
====Australia====<br />
<br />
;[http://groups.google.com/group/fp-syd FP-SYD, the Sydney (Australia) Functional Programming group]<br />
:FP hackers in Sydney.<br />
<br />
;[http://sites.google.com/site/fpunion/ (FPU) Melbourne Functional Programming Union]<br />
:The FPU is a collective of functional programming language enthusiasts, which has been in operation since 1998. We are based at the University of Melbourne, in the Department of Computer Science and Software Engineering, but we are open to all members of the community. We meet on a regular basis for lively discussions on topics broadly associated with the declarative programming paradigm.<br />
<br />
;[http://bfpg.org/ Brisbane Functional Programming Group (BFPG)] ([http://www.meetup.com/Brisbane-Functional-Programming-Group-BFG/ Meetup page])<br />
:A group for Functional Programming with Haskell, Scala and other languages.<br />
<br />
;[http://meetup.com/PerthFP/ Perth Functional Programmers Meetup]<br />
:A group in Perth, WA for Functional Programming with Haskell, Scala and other languages.<br />
<br />
===South America===<br />
<br />
==== Bolivia ====<br />
; [https://www.facebook.com/groups/111518795538430/ Comunidad Haskell San Simon (CHSS)]<br />
: Haskell user group for Bolivia and spanish speaking community<br />
<br />
====Brazil====<br />
;[[User_groups/Brazil|Grupo Brasileiro de Usuários de Haskell]]<br />
: Grupo criado para reunir os desenvolvedores e entusiastas que utilizam Haskell no Brasil<br />
<br />
== Workshops/meet ups ==<br />
<br />
Less regular, and move around. Usually have a few talks from invited speakers.<br />
See the [[Haskell]] homepage for a list of upcoming events.<br />
<br />
== Hackathons ==<br />
<br />
Getting together to squash bugs and write new stuff. For a list of past and upcoming hackathons, see the [[Hackathon]] page.<br />
<br />
== Conferences ==<br />
<br />
See the [[Haskell_in_research#Conferences|Haskell in research]] and [[Conferences]] page for academic workshops and conferences<br />
focusing on Haskell and related technology.</div>Heisenbughttps://wiki.haskell.org/index.php?title=HaskellImplementorsWorkshop/2015&diff=60178HaskellImplementorsWorkshop/20152015-09-30T22:31:39Z<p>Heisenbug: Typos</p>
<hr />
<div>The Haskell implementors' workshop is a forum for those involved in<br />
implementing Haskell systems, infrastructure, libraries and tools,<br />
generally for people involved in implementing Haskell technology, to<br />
share their work and discuss future directions and collaborations with<br />
others.<br />
<br />
In 2015, the Haskell Implementors Workshop will be co-located with [http://www.icfpconference.org/icfp2015/ ICFP 2015] in Vancouver. <br />
<br />
The workshop does not have proceedings. Talks and/or demos are proposed by<br />
submitting an abstract, and selected by a small program committee.<br />
The workshop will be informal and interactive, with a flexible timetable<br />
and plenty of room for ad-hoc discussion, demos, and impromptu short talks.<br />
<br />
Traditionally, HIW is an open forum for people writing compilers, tools, or <br />
libraries, people with cool ideas for directions in which we should take<br />
the platform, proposals for new features to be implemented, and <br />
half-baked crazy ideas. For more details see the [http://www.haskell.org/haskellwiki/HaskellImplementorsWorkshop/2015/Call_for_Contributions Call for Contributions] in full.<br />
<br />
<br />
== Links ==<br />
<br />
* [http://www.haskell.org/haskellwiki/HaskellImplementorsWorkshop/2015/Call_for_Contributions Call for Contributions]<br />
* [https://icfp-hiw15.hotcrp.com/ HotCRP Submission page]<br />
<br />
== Important Dates ==<br />
<br />
* '''Tuesday, 4 August, 2015''': Talk Proposal Deadline (anywhere on earth)<br />
* '''Monday, 10 August, 2015''': Notification<br />
* '''Sunday, 30 August, 2015''': Workshop<br />
<br />
== Programme ==<br />
{|<br />
<br />
| '''09:00''' || '''Welcome to HIW 2015'''<br />
|-<br />
| '''09:05-10:00 || '''Session 1'''<br />
|-<br />
| '''09:05''' || State of the GHC ([https://wiki.haskell.org/wikiupload/c/c8/GHC_Sept15.pptx slides]) ([https://youtu.be/ga83zOo95bs video])<br />
|-<br />
| '''09:35''' || [[#The state of GHCJS|State of the GHCJS]] ([https://wiki.haskell.org/wikiupload/9/95/HIW15-Stegeman-The_State_of_the_GHCJS.pdf slides]) ([https://youtu.be/ZEUTndOzrvw video])<br />
|-<br />
| '''10:00 - 10:30''' || '''Coffee Break'''<br />
|-<br />
| '''10:30-12:00''' || '''Session 2'''<br />
|-<br />
| '''10:30''' || [[#API Annotations - enabler for source code round tripping / modification|API Annotations - enabler for source code round tripping / modification]] ([https://wiki.haskell.org/wikiupload/d/d5/API_Annotations.pdf slides]) ([https://youtu.be/U5_9mfQAUBo video])<br />
|-<br />
| '''11:00''' || [[#Using hardware transactions in the GHC runtime system|Using hardware transactions in the GHC runtime system]] ([http://goo.gl/8wVAR5 slides]) ([https://youtu.be/OwxI4BvfCp4 video])<br />
|-<br />
| '''11:30''' || [[#Rebooting supercompilation for GHC|Rebooting supercompilation for GHC]] ([https://github.com/osa1/HIW/blob/master/HIW_second_try.pdf slides]) ([https://youtu.be/gkx-D-7Y1EU video])<br />
|-<br />
| '''12:00-14:00''' || '''Lunch'''<br />
|-<br />
| '''14:00-15:30''' || '''Session 3'''<br />
|-<br />
| '''14:00''' || [[#Securing our package distribution system|Securing our package distribution system]] ([https://wiki.haskell.org/wikiupload/a/af/HackageSecurity.pdf slides]) ([https://youtu.be/D9juHHlnayI video])<br />
|-<br />
| '''14:25''' || [[#Introduction to the 'stack' build tool|Introduction to the 'stack' build tool]] ([https://cdn.rawgit.com/borsboom/ab5a1b859ca5619c2f8b/raw/daed4210f6a5d7293e6a59d23b5ae875b8679f1a/slides.html slides]) ([https://youtu.be/RRmb2RtU0hU video])<br />
|-<br />
| '''14:50''' || [[#"Look Ma, No Signatures!" Separate modular development without interfaces|"Look Ma, No Signatures!" Separate modular development without interfaces]] ([https://wiki.haskell.org/wikiupload/9/92/Hiw-backpack-infer.pdf slides]) ([https://youtu.be/PrDSxnO29d0 video])<br />
|-<br />
| ''' 15:15''' || [[#Haskell.org Infrastructure Status Update|Haskell.org Infrastructure Status Update]] ([https://wiki.haskell.org/wikiupload/4/42/Infra-status-15.pdf slides]) ([https://youtu.be/cblJf84nkj8 video])<br />
|-<br />
| '''15:30-16:00''' || '''Coffee Break'''<br />
|-<br />
| '''16:00-18:00''' || '''Session 4'''<br />
|-<br />
| '''16:00''' || [[#A Pretty-Printer that Says what it Means|A Pretty-Printer that Says what it Means]] ([https://wiki.haskell.org/wikiupload/4/4c/Hiw-2015-david-christiansen.pdf slides]) ([https://youtu.be/m7BBCcIDXSg video])<br />
|-<br />
| '''16:30''' || [[#Levity Polymorphism in Dependent Haskell|Levity Polymorphism in Dependent Haskell]] ([https://wiki.haskell.org/wikiupload/d/d9/Eisenberg-hiw-2015.pdf slides]) ([https://youtu.be/gn_ho6amc7U video])<br />
|-<br />
| '''17.00''' || '''Lightning talks'''<br />
|}<br />
<br />
'''Lightning talks''':<br />
* Talk 1: It's the data, stupid (Ryan Newton) ([http://www.cs.indiana.edu/~rrnewton/talks/2015_08_HIW_lightning_talk.pdf slides]) ([https://youtu.be/TT4poCUSf3A video])<br />
* Talk 2: GHC Performance Dashboard (Joachim Breitner) ([https://youtu.be/0nWT390n88I video])<br />
* Talk 3: JITs for Haskell (Comeron Swords, Spenser Bauman) ([https://youtu.be/vBPF1zDwyq0 video])<br />
* Talk 4: Into the fold (Ryan Scott) ([https://youtu.be/lTpVN8KQOOg video])<br />
* Talk 5: Unlifted data structures (Edward Kemett) ([https://youtu.be/I1FuZrDhOEk video])<br />
* Talk 6: Progress on cabal and hackage (Duncan Coutts) ([https://youtu.be/VUW8L56JFqc video])<br />
* Talk 7: Declaration-based code distribution (Philipp Schuster) ([https://youtu.be/owRZCA-dDVo video])<br />
<br />
== Abstracts of Accepted Talks ==<br />
<br />
=== ''The state of GHCJS'' ===<br />
Luite Stegeman<br />
<br />
GHCJS is a Haskell to JavaScript compiler based on GHC. Among the improvements in the past year are official Cabal integration, support for CPU profiling and an overhaul of the ghcjs-base library. A recent addition is an experimental REPL, making it easier than ever to interact with Haskell in a browser or node.js environment.<br />
<br />
I will discuss the current state of GHCJS and the ongoing work on the new code generator, including the plans on how to make the most out of the new ECMAScript 2015 features.<br />
<br />
=== ''API Annotations - enabler for source code round tripping / modification'' ===<br />
Alan Zimmerman<br />
<br />
GHC developers will have seen a large number of commits over the last months for API Annotations.<br />
<br />
This talk will focus on what they are, what they are intended for, and show how they are used to round trip source code in ghc-exactprint, which paves the way for a general-purpose haskell source modification library.<br />
<br />
It will touch on the design principles in ghc-exactprint, and will include demonstrations of use in HaRe and Matt Pickering's GSOC project to apply HLint hints directly.<br />
<br />
=== ''Using hardware transactions in the GHC runtime system'' ===<br />
Ryan Yates and Michael L. Scott (University of Rochester)<br />
<br />
<br />
Hardware support for transactional memory (HTM) is now mainstream with commercial offerings from both Intel and IBM. This new flexible hardware tool for synchronization gives opportunities to improve the performance of language-level synchronization and to simplify runtime system implementation. Our research has shown that concurrent data structure performance in GHC is limited when taking the simple but common approach of atomically updating a global mutable reference to the root of a pure-functional structure. Transactional memory (both the existing software implementation and our hybrid hardware/software implementation) shows much better performance as the core count grows. Our current work aims to further improve performance by reducing the overhead of transactional memory in GHC while still supporting such powerful high-level features as retry and orElse. In our talk we will share our benchmark results on a 72-thread Intel machine with HTM, details on how we have found HTM useful in the GHC runtime system, opportunities to explore other uses of HTM, and some lessons learned while working with GHC.<br />
<br />
(This work was funded in part by the National Science Foundation under grants CCR-0963759, CCF-1116055, CCF-1337224, and CCF-1422649, and by support from the IBM Canada Centres for Advanced Studies.)<br />
<br />
[http://goo.gl/8wVAR5 Slides]<br />
<br />
=== ''Rebooting supercompilation for GHC'' ===<br />
Ömer S. Ağacan and Ryan R. Newton (Indiana University)<br />
<br />
GHC's purely functional intermediate language Core, and API for Core-to-Core transformations, make it a great language for experimenting with program transformation ideas. These program transformers can be distributed as libraries, avoiding merging experimental ideas into GHC while making it possible for users to gain advantage of those transformers immediately.<br />
<br />
These compiler plugins, however, are not yet used much in the wild [1]. In the future, we hope to see both more specialized optimizers and extreme optimization modes (“-O99”). In this talk, I will give an overview of recent developments in program-transformation-based optimizations of Haskell, and its history (à la Peyton-Jones and Santos, 1997), with focus on the supercompilation work of Mitchell [2] and Bolingbroke [3]. I argue that it is worth rebooting supercompilation work in GHC, with the aim of providing a compiler plugin as an optional tool for libraries that benefit from it. I will describe my preliminary work in this area, and discuss future directions.<br />
<br />
Lastly, as a new PhD student, I'm going to ask audience for feedback, further ideas and collaborators for Haskell program-transformation-based optimizations and supercompilation work.<br />
<br />
[1]: One example that makes use of it is SYB optimizer described in the paper "Optimizing SYB is Easy!" by Adams et al.<br />
<br />
[2]: Rethinking supercompilation, ICFP '10.<br />
<br />
[3]: Call-by-need supercompilation, PhD thesis.<br />
<br />
=== ''Securing our package distribution system'' ===<br />
Duncan Coutts and Edsko de Vries (Well-Typed)<br />
<br />
As Haskell has gained in popularity and profile there has been increasing pressure to properly secure our package distribution system. This is no small problem as crypto system design is notoriously subtle.<br />
<br />
This talk presents the design and implementation of a system to improve the security of the distribution channel between authors and users via Hackage repositories and mirrors. To reduce the dangers of poor crypto design the system is an adaptation of an existing design from the academic literature called The Update Framework.<br />
<br />
We will introduce The Update Framework, the details of the adaptation to fit the existing Hackage distribution system, and exactly what security guarantees it provides. We will cover the current state of the implementation and other system benefits such as improved performance and reliability from being able to use mirrors -- without having to trust those mirrors.<br />
<br />
=== ''Introduction to the 'stack' build tool'' ===<br />
Emanuel Borsboom (FP Complete)<br />
<br />
Stack is a cross-platform tool for developing Haskell projects, aimed at Haskellers both new and experienced. I will discuss its features and advantages over the current approach, a brief demo of how to use the tool, how it fits into the existing ecosystem, and what it is not.<br />
<br />
[https://cdn.rawgit.com/borsboom/ab5a1b859ca5619c2f8b/raw/daed4210f6a5d7293e6a59d23b5ae875b8679f1a/slides.html Slides] ([https://gist.github.com/borsboom/ab5a1b859ca5619c2f8b#file-slides-md markdown])<br />
<br />
=== ''"Look Ma, No Signatures!" Separate modular development without interfaces'' ===<br />
Edward Z. Yang (Stanford University)<br />
<br />
Standard practice in the Haskell community is to directly depend on libraries you need, specifying the acceptable choice of libraries by version bounds. The Backpack project seeks to raise the level of type-safety, by giving users the tool-support they need to talk interfaces rather than version ranges. Unfortunately, if hs-boot files are any indication, Haskell users hate having to write their type signatures multiple times. In this talk, I want describe a proposal for inferring Backpack signatures from modules. The key idea? Use multiple levels of hs-boot files. There are many benefits (say goodbye to hs-boot files of all types) and also some dangers (how should we manage data kind promotion?)<br />
<br />
=== ''Haskell.org Infrastructure Status Update'' ===<br />
Gershom Bazerman (Haskell.org Committee)<br />
<br />
This brief (ten minute) informational talk will run through the current state of core haskell.org infrastructure -- what has been accomplished in the last year, and what issues remain outstanding to address.<br />
<br />
[https://wiki.haskell.org/wikiupload/4/42/Infra-status-15.pdf Slides]<br />
<br />
=== ''A Pretty-Printer that Says what it Means'' ===<br />
David Raymond Christiansen (IT University of Copenhagen)<br />
<br />
Information from our development tools should be more than mere strings. Regions of the output refer to actual language concepts, but this linkage between sense and reference is lost during ordinary pretty-printing. Making this linkage explicit enables clients of the pretty-printer to produce a variety of innovative and useful tools.<br />
<br />
The pretty-printing library used in Idris abstracts its type of documents over arbitrary semantic annotations. This has enabled a surprising variety of interaction patterns, both in editor modes and other tools. In this talk, I'll describe the approach taken by Idris's pretty-printing library as well as demonstrate some of the applications that this has enabled, with an eye towards their potential implementation in Haskell compilers.<br />
<br />
=== ''Levity Polymorphism in Dependent Haskell'' ===<br />
Richard A. Eisenberg (University of Pennsylvania) <br />
<br />
Along the way to making Haskell dependently typed, it is necessary to introduce explicit kind equalities, much like the explicit type equalities already present in GHC. The theory behind this idea is explored in previous work [1]. However, in implementing kind equalities, several practical challenges presented themselves.<br />
<br />
This talk will focus on one such challenge: resolving GHC's sub-kinding story. GHC 7.10 (and many previous versions) has a base kind * that classifies lifted types (that is, types inhabited by bottom) and a separate base kind # that classifies unlifted types. There is a third kind, spelled OpenKind, that is a super-kind to both * and #. This is necessary to allow, for example, exceptions to be thrown in a context expecting an unlifted type. However, mixing explicit kind equalities and a sub-kinding relationship would be quite intricate. Instead, we use polymorphism to model sub-typing by introducing so-called levity variables and indexing the base kinds by these levity variables. The details will be in the talk. One upshot of this solution is that it will be possible for Haskellers to write their own functions that work at both * and # kinds, something impossible today.<br />
<br />
This talk will also include time to demo a working implementation of GHC that merges types with kinds and reasons about kind equalities.<br />
<br />
[1]: Stephanie Weirich, Justin Hsu, and Richard A. Eisenberg. "System FC with Explicit Kind Equality". ICFP '13.<br />
<br />
[https://wiki.haskell.org/wikiupload/d/d9/Eisenberg-hiw-2015.pdf Slides]<br />
<br />
== Programme Committee ==<br />
<br />
* Christopher Brown (St. Andrews University)<br />
* Richard Eisenberg (University of Pennsylvania)<br />
* Edward Kmett (S&P Capital IQ)<br />
* Hans-Wolfgang Loidl (Heriot-Watt University)<br />
* Trevor L. McDonell (Indiana University)<br />
* Deian Stefan (UC San Diego and GitStar)<br />
* Josef Svenningsson - chair (Chalmers University of Technology)<br />
<br />
[[Category:Community]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=ZuriHac2015/Projects&diff=59800ZuriHac2015/Projects2015-05-29T09:07:29Z<p>Heisenbug: /* List of Projects */</p>
<hr />
<div>A good way to learn more about Haskell and exchange ideas is to get together with like-minded Haskellers and tackle an interesting project or get familiar with some of the open-source projects in the Haskell community like [https://ghc.haskell.org/trac/ghc/wiki/WorkingConventions GHC], [https://github.com/haskell/cabal/issues cabal], or one of the many libraries on [https://hackage.haskell.org/ Hackage].<br />
<br />
This page serves as a meeting place for Haskellers that are looking for other Haskellers to work on a common project. Feel free to add your project or your name to a project below as it was done for [[ZuriHac2014/Projects|ZuriHac 2014]].<br />
<br />
= List of Projects =<br />
<br />
{|<br />
|-<br />
! Project Name !! Contact Name !! Project Licence !! Project Home Page<br />
|-<br />
| LambdaCube 3D || Csaba Hruska, Péter Diviánszky || BSD3 || [http://lambdacube3d.com/ lambdacube3d.com]<br />
|-<br />
| [[/Gipeda|Gipeda]] performance dashboard || Joachim Breitner || MIT || [https://github.com/nomeata/gipeda GitHub]<br />
|-<br />
| [[/fficxx|fficxx]] Haskell-C++ FFI generator || Ian-Woo Kim || BSD3 || [https://github.com/wavewave/fficxx GitHub] [http://ianwookim.org/fficxx HomePage]<br />
|-<br />
| [[/hackage-security|Cabal & Hackage hacking]] || Duncan Coutts || BSD3 || [https://github.com/haskell/cabal Cabal] and [https://github.com/haskell/hackage-server Hackage]<br />
|-<br />
| [[/FRPGames|FRP games]] || Ivan Perez || BSD3 ||<br />
[http://github.com/ivanperez-keera/Yampa github]<br />
|-<br />
| darcs/darcsden || Ganesh Sittampalam || GPL || http://darcs.net<br />
|-<br />
| Cloud Haskell || Mathieu Boespflug, Alexander Vershilov || BSD3 || http://haskell-distributed.github.io/<br />
|-<br />
| learn (+document) Debian Packaging of Haskell stuff || Thomas Koch (thkoch) || --- || https://wiki.debian.org/Haskell<br />
|-<br />
| in-memory data type compression for GHC || Gabor Greif (irc:heisenbug) || --- || https://ghc.haskell.org/trac/summer-of-code/ticket/1669<br />
|}<br />
<br />
= Keysigning =<br />
<br />
Just find people who want to do keysigning and do it:<br />
<br />
* Thomas Koch (thkoch)<br />
* (bazzle)</div>Heisenbughttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Hardware_verification&diff=59078Applications and libraries/Hardware verification2014-11-04T11:47:26Z<p>Heisenbug: add Conal's stuff</p>
<hr />
<div>== Applications ==<br />
<br />
;[https://forsyde.ict.kth.se ForSyDe] <br />
: The ForSyDe (Formal System Design) methodology is implemented as a Haskell-based DSL. ForSyDe's embedded compiler is capable of translating system models to synthesizable VHDL. Moreover it is able to interface with third party EDA tools such as Altera's [http://www.model.com/ Modelsim] and [http://www.altera.com/products/software/quartus-ii/subscription-edition/qts-se-index.html Quartus II].<br />
<br />
;Atom<br />
:Atom is a hardware description language embedded in Haskell. Atom compiles conditional term rewriting systems to Verilog and VHDL for IC simulation, verification, and synthesis.<br />
<br />
;[http://www.macs.hw.ac.uk/~gnik/apset/circuit_simulator.lhs Circuit Simulator]<br />
:David J. King and John O'Donnell's digital circuit simulator<br />
<br />
;Hawk---Specifying and Prototyping Microprocessors<br />
:The goal of the Hawk project is to develop a language for expressing highly abstracted specifications of modern microprocessor designs, to provide design teams with the ability to dynamically explore a wide range of design choices. The Hawk language is Haskell plus the Hawk library. The original link at http://www.cse.ogi.edu/PacSoft/projects/Hawk/ seems to be no longer live.<br />
<br />
;[http://wiki.cs.pdx.edu/bartforge/chortl.html Chortl]<br />
:Chortl is an extremely simple Haskell EDSL for hardware description. Chortl supports multiple backends. The current backend generates Verilog, and is intended for FPGA designs; near-future intent is to implement backends to generate C, and to provide graphical circuit diagrams. Chortl features include simplicity, a notation reasonably comprehensible by HW folks, the ability to define custom "components" such as adder trees in full Haskell, simplicity, and simplicity. Chortl is in a very early stage of development, so feedback and help are greatly appreciated.<br />
<br />
;[http://clash.ewi.utwente.nl CλaSH]<br />
:CλaSH abstractly interprets (and optimizes) Haskell to netlists (and outputs them as VHDL code).<br />
<br />
;[http://www.cs.chalmers.se/~koen/Lava/ Lava], [http://raintown.org/lava/ Lava for Xilinx]<br />
:Lava is a hardware description language based upon Haskell.<br />
<br />
;[http://conal.net/blog/posts/haskell-to-hardware-via-cccs Conal Elliott's Work]<br />
:CCC-HDL is described in his blog posts.<br />
<br />
{{LibrariesPage}}</div>Heisenbughttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Hardware_verification&diff=59077Applications and libraries/Hardware verification2014-11-04T11:43:58Z<p>Heisenbug: paren</p>
<hr />
<div>== Applications ==<br />
<br />
;[https://forsyde.ict.kth.se ForSyDe] <br />
: The ForSyDe (Formal System Design) methodology is implemented as a Haskell-based DSL. ForSyDe's embedded compiler is capable of translating system models to synthesizable VHDL. Moreover it is able to interface with third party EDA tools such as Altera's [http://www.model.com/ Modelsim] and [http://www.altera.com/products/software/quartus-ii/subscription-edition/qts-se-index.html Quartus II].<br />
<br />
;Atom<br />
:Atom is a hardware description language embedded in Haskell. Atom compiles conditional term rewriting systems to Verilog and VHDL for IC simulation, verification, and synthesis.<br />
<br />
;[http://www.macs.hw.ac.uk/~gnik/apset/circuit_simulator.lhs Circuit Simulator]<br />
:David J. King and John O'Donnell's digital circuit simulator<br />
<br />
;Hawk---Specifying and Prototyping Microprocessors<br />
:The goal of the Hawk project is to develop a language for expressing highly abstracted specifications of modern microprocessor designs, to provide design teams with the ability to dynamically explore a wide range of design choices. The Hawk language is Haskell plus the Hawk library. The original link at http://www.cse.ogi.edu/PacSoft/projects/Hawk/ seems to be no longer live.<br />
<br />
;[http://wiki.cs.pdx.edu/bartforge/chortl.html Chortl]<br />
:Chortl is an extremely simple Haskell EDSL for hardware description. Chortl supports multiple backends. The current backend generates Verilog, and is intended for FPGA designs; near-future intent is to implement backends to generate C, and to provide graphical circuit diagrams. Chortl features include simplicity, a notation reasonably comprehensible by HW folks, the ability to define custom "components" such as adder trees in full Haskell, simplicity, and simplicity. Chortl is in a very early stage of development, so feedback and help are greatly appreciated.<br />
<br />
;[http://clash.ewi.utwente.nl CλaSH]<br />
:CλaSH abstractly interprets (and optimizes) Haskell to netlists (and outputs them as VHDL code).<br />
<br />
;[http://www.cs.chalmers.se/~koen/Lava/ Lava], [http://raintown.org/lava/ Lava for Xilinx]<br />
:Lava is a hardware description language based upon Haskell.<br />
<br />
{{LibrariesPage}}</div>Heisenbughttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Hardware_verification&diff=59076Applications and libraries/Hardware verification2014-11-04T11:43:31Z<p>Heisenbug: spelling</p>
<hr />
<div>== Applications ==<br />
<br />
;[https://forsyde.ict.kth.se ForSyDe] <br />
: The ForSyDe (Formal System Design) methodology is implemented as a Haskell-based DSL. ForSyDe's embedded compiler is capable of translating system models to synthesizable VHDL. Moreover it is able to interface with third party EDA tools such as Altera's [http://www.model.com/ Modelsim] and [http://www.altera.com/products/software/quartus-ii/subscription-edition/qts-se-index.html Quartus II].<br />
<br />
;Atom<br />
:Atom is a hardware description language embedded in Haskell. Atom compiles conditional term rewriting systems to Verilog and VHDL for IC simulation, verification, and synthesis.<br />
<br />
;[http://www.macs.hw.ac.uk/~gnik/apset/circuit_simulator.lhs Circuit Simulator]<br />
:David J. King and John O'Donnell's digital circuit simulator<br />
<br />
;Hawk---Specifying and Prototyping Microprocessors<br />
:The goal of the Hawk project is to develop a language for expressing highly abstracted specifications of modern microprocessor designs, to provide design teams with the ability to dynamically explore a wide range of design choices. The Hawk language is Haskell plus the Hawk library. The original link at http://www.cse.ogi.edu/PacSoft/projects/Hawk/ seems to be no longer live.<br />
<br />
;[http://wiki.cs.pdx.edu/bartforge/chortl.html Chortl]<br />
:Chortl is an extremely simple Haskell EDSL for hardware description. Chortl supports multiple backends. The current backend generates Verilog, and is intended for FPGA designs; near-future intent is to implement backends to generate C, and to provide graphical circuit diagrams. Chortl features include simplicity, a notation reasonably comprehensible by HW folks, the ability to define custom "components" such as adder trees in full Haskell, simplicity, and simplicity. Chortl is in a very early stage of development, so feedback and help are greatly appreciated.<br />
<br />
;[http://clash.ewi.utwente.nl CλaSH]<br />
:CλaSH abstractly interprets (and optimizes) Haskell to netlists (and outputs them as VHDL code.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Lava/ Lava], [http://raintown.org/lava/ Lava for Xilinx]<br />
:Lava is a hardware description language based upon Haskell.<br />
<br />
{{LibrariesPage}}</div>Heisenbughttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Hardware_verification&diff=59075Applications and libraries/Hardware verification2014-11-04T11:41:27Z<p>Heisenbug: add ClaSH</p>
<hr />
<div>== Applications ==<br />
<br />
;[https://forsyde.ict.kth.se ForSyDe] <br />
: The ForSyDe (Formal System Design) methodology is implemented as a Haskell-based DSL. ForSyDe's embedded compiler is capable of translating system models to synthesizable VHDL. Moreover it is able to interface with third party EDA tools such as Altera's [http://www.model.com/ Modelsim] and [http://www.altera.com/products/software/quartus-ii/subscription-edition/qts-se-index.html Quartus II].<br />
<br />
;Atom<br />
:Atom is a hardware description language embedded in Haskell. Atom compiles conditional term rewriting systems to Verilog and VHDL for IC simulation, verification, and synthesis.<br />
<br />
;[http://www.macs.hw.ac.uk/~gnik/apset/circuit_simulator.lhs Circuit Simulator]<br />
:David J. King and John O'Donnell's digital circuit simulator<br />
<br />
;Hawk---Specifying and Prototyping Microprocessors<br />
:The goal of the Hawk project is to develop a language for expressing highly abstracted specifications of modern microprocessor designs, to provide design teams with the ability to dynamically explore a wide range of design choices. The Hawk language is Haskell plus the Hawk library. The original link at http://www.cse.ogi.edu/PacSoft/projects/Hawk/ seems to be no longer live.<br />
<br />
;[http://wiki.cs.pdx.edu/bartforge/chortl.html Chortl]<br />
:Chortl is an extremely simple Haskell EDSL for hardware description. Chortl supports multiple backends. The current backend generates Verilog, and is intended for FPGA designs; near-future intent is to implement backends to generate C, and to provide graphical circuit diagrams. Chortl features include simplicity, a notation reasonably comprehensible by HW folks, the ability to define custom "components" such as adder trees in full Haskell, simplicity, and simplicity. Chortl is in a very early stage of development, so feedback and help are greatly appreciated.<br />
<br />
;[http://clash.ewi.utwente.nl ClaSH]<br />
:Clash abstractly interprets (and optimizes) Haskell to netlists (and outputs them as VHDL code.<br />
<br />
;[http://www.cs.chalmers.se/~koen/Lava/ Lava], [http://raintown.org/lava/ Lava for Xilinx]<br />
:Lava is a hardware description language based upon Haskell.<br />
<br />
{{LibrariesPage}}</div>Heisenbughttps://wiki.haskell.org/index.php?title=HacBerlin2014&diff=58813HacBerlin20142014-09-14T18:29:32Z<p>Heisenbug: another typo</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 preliminary [[/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 />
=== 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>Heisenbughttps://wiki.haskell.org/index.php?title=HacBerlin2014&diff=58812HacBerlin20142014-09-14T18:27:12Z<p>Heisenbug: typos</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 preliminary [[/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 />
=== 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 />
=== Accomodation ===<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>Heisenbughttps://wiki.haskell.org/index.php?title=ZuriHac2014&diff=58302ZuriHac20142014-06-08T15:47:02Z<p>Heisenbug: grammar</p>
<hr />
<div>[[Image:ZuriHac2014.png|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|Friday 6 June 2014 - Sunday 8 June 2014<br />
|-<br />
|Hours:<br />
|09:00 ~ 20:00<br />
|-<br />
|Where:<br />
|Better <small>(formerly known as Erudify)</small>, Zurich, Switzerland<br />
|}<br />
----<br />
<br />
<big>Talks from:<br>[[File:Simon_Marlow.jpg|50px]] [http://community.haskell.org/~simonmar/ Simon Marlow] & [[File:Edward_Kmett.jpg|50px]] [https://github.com/ekmett Edward Kmett]!</big><br />
<br />
'''Important:'''<br><br />
ZuriHac has reached capacity. Registration is now closed. Thank you for your understanding.<br />
<br />
'''Important:'''<br><br />
Switzerland has [http://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#Swiss_SEV_1011_.28Type_J.29 its own power sockets]. We can't provide converters for everybody so make sure to bring one along. Do note that the [http://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7.2F16_.22Europlug.22_.28Type_C.29 Europlug] will fit in a Swiss power socket. There's an electronics shop [https://maps.google.ch/maps?q=Fust+Center+Eschenmoser&hl=en&cid=6177809817081314569&gl=CH&t=m&z=16&iwloc=A Fust Center Eschenmoser] very near our office where you can buy converters.<br />
<br />
&nbsp;<br />
<br />
== About ==<br />
<br />
On the first weekend of June 2014 the Zurich HaskellerZ Meetup group will organize ZuriHac 2014, a three day Haskell Hackathon hosted at the Better offices. This is the third Haskell Hackathon in Zurich. The previous two were [[ZuriHac2013]] and [[ZuriHac2010]].<br />
<br />
The Haskell Hackathon is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure.<br />
<br />
This is a great opportunity to meet your fellow haskellers in real life,<br />
find new contributors for your project, improve existing libraries and tools or<br />
even start new ones!<br />
<br />
Note that this event is open to ''any'' experience level, from beginners to guru's. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community.<br />
<br />
== Sponsors ==<br />
<br />
[[File:better.png|300px]]<br />
<br />
[http://better.com Better] (formerly known as Erudify) will host the Hackathon.<br />
<br />
[[File:Google.png|230px]]<br />
<br />
[http://www.google.com/about/jobs/locations/zurich/ Google Switzerland] is providing financial support<br />
<br />
== News ==<br />
<br />
;17 November 2013<br />
:Added wiki page<br />
<br />
;22 January 2014<br />
:Opened [http://bit.ly/ZuriHac2014 registration]<br />
<br />
;28 April 2014<br />
:Reached capacity. Registration is now closed.<br />
<br />
== Registration ==<br />
ZuriHac has reached capacity so the registration has been closed. Thank you for your understanding.<br />
<br />
== Attendees ==<br />
See [[/Attendees|the list of people]] who have signed up for ZuriHac 2014.<br />
<br />
== Location ==<br />
[[File:ZurichMontage.jpg|300px|right]]<br />
<br />
'''Zurich, Switzerland'''<br />
<br />
To learn more about the city, please see the [http://en.wikipedia.org/wiki/Zurich '''Wikipedia'''] and [http://wikitravel.org/en/Zurich '''Wikitravel'''] articles.<br />
<br />
* ZuriHac will be hosted at the Better offices, [https://maps.google.ch/maps?q=Gr%C3%BCngasse+19,+Z%C3%BCrich&hl=en&ie=UTF8&ll=47.372947,8.525573&spn=0.008734,0.009559&sll=47.373386,8.524925&layer=c&cbp=13,222.55,,0,0.06&cbll=47.373504,8.525083&hnear=Gr%C3%BCngasse+19,+Kreis+4,+8004+Z%C3%BCrich&t=h&z=17&iwloc=A&panoid=vqb-ZHsYZ3d-SIhVYQeEoQ Grüngasse 19, Zürich].<br />
<br />
=== Getting around ===<br />
<br />
[https://mapsengine.google.com/map/edit?mid=zvSr4yOfKWIQ.k0KI-gCF1DnU Google map with important places]<br />
<br />
Local transport links:<br />
<br />
http://www.zvv.ch/en/<br />
<br />
'''A note on day tickets:'''<br />
<br />
Day tickets in Zurich run for 24 hours and can be used on all forms of transport, bus, train, tram.<br />
<br />
You can buy tickets from [http://www.zvv.ch/en/tickets/automatic-ticket-machine/index.html the ticket machines].<br />
<br />
== Accommodation ==<br />
<br />
We recommend the following accommodation options:<br />
<br />
* http://www.langstars.com/en/ Youthhostel, CHF 50 per night.<br />
<br />
* https://www.airbnb.com/ Airbnb, variable.<br />
<br />
* Hotel Neufeld, http://www.hotel-neufeld.ch/.<br />
<br />
== Schedule ==<br />
<br />
=== Friday ===<br />
<br />
Hacking hours: 10:00 to 18:00.<br />
<br />
==== Introduction ====<br />
<br />
Please come before '''11:00'''. At 11:00 there will be projects introduction and discussion.<br />
<br />
==== Talk by Edward Kmett ====<br />
<br />
Title: Functionally Oblivious and Succinct<br />
<br />
Time: 17:00<br />
<br />
Abstract:<br />
This talk provides a whirlwind tour of some new types of functional data structures and their applications.<br />
<br />
Cache-oblivious algorithms let us perform optimally for all cache levels in your system at the same time by optimizing for one cache for which we don't know the parameters. While Okasaki's "Purely Functional Data Structures" taught us how to reason about asymptotic performance in a lazy language like Haskell, reasoning about cache-oblivious algorithms requires some new techniques.<br />
<br />
Succinct data structures let us work directly on near-optimally compressed data representations without decompressing.<br />
<br />
How can we derive new functional data structures from these techniques? Applications include just diverse areas as speeding up a variant of Haskell's venerable Data.Map, handling "big data" on disk without tuning for hardware, and parsing JSON faster in less memory.<br />
<br />
==== Haskell Katas ====<br />
<br />
=== Saturday ===<br />
<br />
Doors open at 10:00.<br />
<br />
==== Talk by Simon Marlow ====<br />
<br />
Title: The Haxl project at Facebook (update)<br />
<br />
Time: 13:30<br />
<br />
Abstract:<br />
The Haxl project aims to build a DSL in Haskell to be used by engineers at Facebook to write rules that catch spam and malware. The key idea is to use an Applicative/Monad abstraction that makes the use of external data efficient and concise, by automatically taking advantage of concurrency and opportunities for batching remote data requests.<br />
<br />
At ZuriHac in August 2013 I gave a talk about Haxl when we had just started. Some 10 months later I'd like to talk about the progress we've made in pushing Haxl towards production use. There will be a lot of details and anecdotes in this talk about our experiences in replacing a large production system with a Haskell-based solution.<br />
<br />
==== BBQ at Lake Zurich ====<br />
<br />
On Saturday afternoon (17:00) we'll go BBQing at the lake.<br />
<br />
The plan is that you buy your own food which you can then grill on the two BBQs we rented at the lake.<br />
<br />
===== Shopping =====<br />
<br />
We'll do a bit of load-balancing while buying the food by splitting into 4 groups that each go to a different shop. Bas will form the groups on Saturday afternoon and post the groups and shopping locations here.<br />
<br />
===== Location =====<br />
<br />
We'll meet at the fountain in the middle of the Blatterwiese park at the east coast of the lake:<br />
<br />
[[File:Blatterwiese_Fountain.jpeg|400px]]<br />
<br />
You can find the BBQ location on the [https://mapsengine.google.com/map/edit?mid=zvSr4yOfKWIQ.k0KI-gCF1DnU map].<br />
<br />
===== Traveling =====<br />
<br />
We recommend going by tram (Line 2) and getting of at the Fröhlichstrasse stop (this stop can also be found on the map).<br />
<br />
=== Sunday ===<br />
<br />
==== Demoday ====<br />
<br />
* Slot 1: 14:00 - 14:05 Greg Horn - parallel cabal install<br />
* Slot 2: 14:05 - 14:10 Martijn van Steenbergen - JsonGrammar<br />
* Slot 3: 14:10 - 14:15 Simon Hengel - [https://github.com/sol/reserve#reserve reserve]: Framework agnostic reloading of Haskell web applications<br />
* Slot 4: 14:15 - 14:20 Ian-Woo Kim - Hoodle<br />
* Slot 5: 14:20 - 14:25 Roman Cheplyaka - Better MTL<br />
* Slot 6: 14:25 - 14:30 Csaba Hruska & Mate Kovacs - LambdaCube and Stunts<br />
* Slot 7: 14:30 - 14:35 Duncan Coutts - Hackage<br />
* Slot 8: 14:35 - 14:40 Roel van Dijk - complexity<br />
* Slot 9: 14:40 - 14:45 Edward Kmett - Category theory through lens<br />
* Slot 10: 14:45 - 14:50<br />
<br />
== Projects ==<br />
See the [[/Projects|projects page]].<br />
<br />
== IRC, Twitter ==<br />
The main communication channel during the Hackathon will be our IRC channel: '''#zurihac''' at Freenode.<br />
<br />
'''#zurihac''' is our Twitter/Google+ hashtag as well.<br />
<br />
== Organizers ==<br />
The events are organized in name of the [http://www.meetup.com/HaskellerZ/ Zurich HaskellerZ meetup group] by the following people:<br />
<br />
* Johan Tibell (Google)<br />
* Alexander Bernauer (Google)<br />
* Nora Kasper (Better)<br />
* Thomas Schilling (Better)<br />
* Simon Meier (Better)<br />
* Dominic Small (Better)<br />
* Bas van Dijk (Better)<br />
<br />
For any questions or emergencies, you can always call Bas ([[File:Bas_van_Dijk.png|50px]]) at +41 791 285 624.<br />
<br />
Or send an email to: <tt>zurihac@better.com</tt><br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=ZuriHac2014&diff=58301ZuriHac20142014-06-08T15:46:03Z<p>Heisenbug: </p>
<hr />
<div>[[Image:ZuriHac2014.png|right]]<br />
<br />
----<br />
{|<br />
|When:<br />
|Friday 6 June 2014 - Sunday 8 June 2014<br />
|-<br />
|Hours:<br />
|09:00 ~ 20:00<br />
|-<br />
|Where:<br />
|Better <small>(formerly known as Erudify)</small>, Zurich, Switzerland<br />
|}<br />
----<br />
<br />
<big>Talks from:<br>[[File:Simon_Marlow.jpg|50px]] [http://community.haskell.org/~simonmar/ Simon Marlow] & [[File:Edward_Kmett.jpg|50px]] [https://github.com/ekmett Edward Kmett]!</big><br />
<br />
'''Important:'''<br><br />
ZuriHac has reached capacity. Registration is now closed. Thank you for your understanding.<br />
<br />
'''Important:'''<br><br />
Switzerland has [http://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#Swiss_SEV_1011_.28Type_J.29 its own power sockets]. We can't provide converters for everybody so make sure to bring one along. Do note that the [http://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7.2F16_.22Europlug.22_.28Type_C.29 Europlug] will fit in a Swiss power socket. There's an electronics shop [https://maps.google.ch/maps?q=Fust+Center+Eschenmoser&hl=en&cid=6177809817081314569&gl=CH&t=m&z=16&iwloc=A Fust Center Eschenmoser] very near our office where you can buy converters.<br />
<br />
&nbsp;<br />
<br />
== About ==<br />
<br />
On the first weekend of June 2014 the Zurich HaskellerZ Meetup group will organize ZuriHac 2014, a three day Haskell Hackathon hosted at the Better offices. This is the third Haskell Hackathon in Zurich. The previous two were [[ZuriHac2013]] and [[ZuriHac2010]].<br />
<br />
The Haskell Hackathon is an international, grassroots collaborative coding festival with a simple focus: build and improve Haskell libraries, tools, and infrastructure.<br />
<br />
This is a great opportunity to meet your fellow haskellers in real life,<br />
find new contributors for your project, improve existing libraries and tools or<br />
even start new ones!<br />
<br />
Note that this event is open to ''any'' experience level, from beginners to guru's. In fact, one of the goals is to bring beginners in contact with experts so that the former can get a quick start in the Haskell community.<br />
<br />
== Sponsors ==<br />
<br />
[[File:better.png|300px]]<br />
<br />
[http://better.com Better] (formerly known as Erudify) will host the Hackathon.<br />
<br />
[[File:Google.png|230px]]<br />
<br />
[http://www.google.com/about/jobs/locations/zurich/ Google Switzerland] is providing financial support<br />
<br />
== News ==<br />
<br />
;17 November 2013<br />
:Added wiki page<br />
<br />
;22 January 2014<br />
:Opened [http://bit.ly/ZuriHac2014 registration]<br />
<br />
;28 April 2014<br />
:Reached capacity. Registration is now closed.<br />
<br />
== Registration ==<br />
ZuriHac has reached capacity so the registration has been closed. Thank you for your understanding.<br />
<br />
== Attendees ==<br />
See [[/Attendees|the list of people]] who have signed up for ZuriHac 2014.<br />
<br />
== Location ==<br />
[[File:ZurichMontage.jpg|300px|right]]<br />
<br />
'''Zurich, Switzerland'''<br />
<br />
To learn more about the city, please see the [http://en.wikipedia.org/wiki/Zurich '''Wikipedia'''] and [http://wikitravel.org/en/Zurich '''Wikitravel'''] articles.<br />
<br />
* ZuriHac will be hosted at the Better offices, [https://maps.google.ch/maps?q=Gr%C3%BCngasse+19,+Z%C3%BCrich&hl=en&ie=UTF8&ll=47.372947,8.525573&spn=0.008734,0.009559&sll=47.373386,8.524925&layer=c&cbp=13,222.55,,0,0.06&cbll=47.373504,8.525083&hnear=Gr%C3%BCngasse+19,+Kreis+4,+8004+Z%C3%BCrich&t=h&z=17&iwloc=A&panoid=vqb-ZHsYZ3d-SIhVYQeEoQ Grüngasse 19, Zürich].<br />
<br />
=== Getting around ===<br />
<br />
[https://mapsengine.google.com/map/edit?mid=zvSr4yOfKWIQ.k0KI-gCF1DnU Google map with important places]<br />
<br />
Local transport links:<br />
<br />
http://www.zvv.ch/en/<br />
<br />
'''A note on day tickets:'''<br />
<br />
Day tickets in Zurich run for 24 hours and can be used on all forms of transport, bus, train, tram.<br />
<br />
You can buy tickets from [http://www.zvv.ch/en/tickets/automatic-ticket-machine/index.html the ticket machines].<br />
<br />
== Accommodation ==<br />
<br />
We recommend the following accommodation options:<br />
<br />
* http://www.langstars.com/en/ Youthhostel, CHF 50 per night.<br />
<br />
* https://www.airbnb.com/ Airbnb, variable.<br />
<br />
* Hotel Neufeld, http://www.hotel-neufeld.ch/.<br />
<br />
== Schedule ==<br />
<br />
=== Friday ===<br />
<br />
Hacking hours: 10:00 to 18:00.<br />
<br />
==== Introduction ====<br />
<br />
Please come before '''11:00'''. At 11:00 there will be projects introduction and discussion.<br />
<br />
==== Talk by Edward Kmett ====<br />
<br />
Title: Functionally Oblivious and Succinct<br />
<br />
Time: 17:00<br />
<br />
Abstract:<br />
This talk provides a whirlwind tour of some new types of functional data structures and their applications.<br />
<br />
Cache-oblivious algorithms let us perform optimally for all cache levels in your system at the same time by optimizing for one cache for which we don't know the parameters. While Okasaki's "Purely Functional Data Structures" taught us how to reason about asymptotic performance in a lazy language like Haskell, reasoning about cache-oblivious algorithms requires some new techniques.<br />
<br />
Succinct data structures let us work directly on near-optimally compressed data representations without decompressing.<br />
<br />
How can derive new functional data structures from these techniques? Applications include just diverse areas as speeding up a variant of Haskell's venerable Data.Map, handling "big data" on disk without tuning for hardware, and parsing JSON faster in less memory.<br />
<br />
==== Haskell Katas ====<br />
<br />
=== Saturday ===<br />
<br />
Doors open at 10:00.<br />
<br />
==== Talk by Simon Marlow ====<br />
<br />
Title: The Haxl project at Facebook (update)<br />
<br />
Time: 13:30<br />
<br />
Abstract:<br />
The Haxl project aims to build a DSL in Haskell to be used by engineers at Facebook to write rules that catch spam and malware. The key idea is to use an Applicative/Monad abstraction that makes the use of external data efficient and concise, by automatically taking advantage of concurrency and opportunities for batching remote data requests.<br />
<br />
At ZuriHac in August 2013 I gave a talk about Haxl when we had just started. Some 10 months later I'd like to talk about the progress we've made in pushing Haxl towards production use. There will be a lot of details and anecdotes in this talk about our experiences in replacing a large production system with a Haskell-based solution.<br />
<br />
==== BBQ at Lake Zurich ====<br />
<br />
On Saturday afternoon (17:00) we'll go BBQing at the lake.<br />
<br />
The plan is that you buy your own food which you can then grill on the two BBQs we rented at the lake.<br />
<br />
===== Shopping =====<br />
<br />
We'll do a bit of load-balancing while buying the food by splitting into 4 groups that each go to a different shop. Bas will form the groups on Saturday afternoon and post the groups and shopping locations here.<br />
<br />
===== Location =====<br />
<br />
We'll meet at the fountain in the middle of the Blatterwiese park at the east coast of the lake:<br />
<br />
[[File:Blatterwiese_Fountain.jpeg|400px]]<br />
<br />
You can find the BBQ location on the [https://mapsengine.google.com/map/edit?mid=zvSr4yOfKWIQ.k0KI-gCF1DnU map].<br />
<br />
===== Traveling =====<br />
<br />
We recommend going by tram (Line 2) and getting of at the Fröhlichstrasse stop (this stop can also be found on the map).<br />
<br />
=== Sunday ===<br />
<br />
==== Demoday ====<br />
<br />
* Slot 1: 14:00 - 14:05 Greg Horn - parallel cabal install<br />
* Slot 2: 14:05 - 14:10 Martijn van Steenbergen - JsonGrammar<br />
* Slot 3: 14:10 - 14:15 Simon Hengel - [https://github.com/sol/reserve#reserve reserve]: Framework agnostic reloading of Haskell web applications<br />
* Slot 4: 14:15 - 14:20 Ian-Woo Kim - Hoodle<br />
* Slot 5: 14:20 - 14:25 Roman Cheplyaka - Better MTL<br />
* Slot 6: 14:25 - 14:30 Csaba Hruska & Mate Kovacs - LambdaCube and Stunts<br />
* Slot 7: 14:30 - 14:35 Duncan Coutts - Hackage<br />
* Slot 8: 14:35 - 14:40 Roel van Dijk - complexity<br />
* Slot 9: 14:40 - 14:45 Edward Kmett - Category theory through lens<br />
* Slot 10: 14:45 - 14:50<br />
<br />
== Projects ==<br />
See the [[/Projects|projects page]].<br />
<br />
== IRC, Twitter ==<br />
The main communication channel during the Hackathon will be our IRC channel: '''#zurihac''' at Freenode.<br />
<br />
'''#zurihac''' is our Twitter/Google+ hashtag as well.<br />
<br />
== Organizers ==<br />
The events are organized in name of the [http://www.meetup.com/HaskellerZ/ Zurich HaskellerZ meetup group] by the following people:<br />
<br />
* Johan Tibell (Google)<br />
* Alexander Bernauer (Google)<br />
* Nora Kasper (Better)<br />
* Thomas Schilling (Better)<br />
* Simon Meier (Better)<br />
* Dominic Small (Better)<br />
* Bas van Dijk (Better)<br />
<br />
For any questions or emergencies, you can always call Bas ([[File:Bas_van_Dijk.png|50px]]) at +41 791 285 624.<br />
<br />
Or send an email to: <tt>zurihac@better.com</tt><br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Diagrams/Dev/Migrate1.2&diff=58244Diagrams/Dev/Migrate1.22014-06-02T08:08:58Z<p>Heisenbug: </p>
<hr />
<div>This page describes breaking API changes between diagrams 1.1 and 1.2, along with explanations of how to migrate to the new 1.2 API.<br />
<br />
== Attributes using Measure ==<br />
<br />
<code>LineWidth</code> is now specified using <code>Measure</code>. This replaces former uses of <code>freeze</code>. See [http://projects.haskell.org/diagrams/doc/manual.html the manual] for full details. The old behavior of <code>lw</code> (in diagrams not using <code>freeze</code>) can be had by using <code>lwL</code>.<br />
<br />
However, in many simple cases, we recommend instead using named line weights provided in <code>Diagrams.TwoD.Attributes</code>. These include <code>thin</code>, <code>thick</code>, and <code>none</code>.<br />
<br />
== Removal of <code>freeze</code> ==<br />
<br />
The <code>freeze</code> function has been removed. Most users probably were not using it; if you were, you have several options for replacing it, depending on how you were using it:<br />
<br />
* If you were just using it to get some lines to scale along with a diagram, use a <code>Local</code> line width (''e.g.'' <code>... # lw (Local 2)</code> or <code>... # lwL 2</code>).<br />
* The above will not work if you were doing non-uniform scaling and really care that the lines should come out looking squished and stretched. In that case, use functions in <code>Diagrams.TwoD.Offset</code> to create a path corresponding to the stroked line, and then fill and transform it normally.<br />
<br />
== Arrows ==<br />
<br />
The size of arrow heads and tails is now specified in terms of length instead of the radius of their circumcircle.<br />
<br />
Gaps at the ends of arrows are now specified using <code>Measure R2</code>.<br />
<br />
The <code>gap</code> traversal has been replaced by `gaps` for consistency in naming, though <code>gap</code> is still provided for backwards compatibility.<br />
<br />
== Reorganization ==<br />
<br />
The <code>avgScale</code> function has been moved from <code>Diagrams.TwoD.Transform</code> to <code>Diagrams.Core.Transform</code>.<br />
<br />
Most (all?) 2D attributes have been moved from <code>Diagrams.Attributes</code> to <code>Diagrams.TwoD.Attributes</code>.<br />
<br />
The <code>Angle</code> definition and related functions have moved to a separate module, <code>Diagrams.Angle</code>.</div>Heisenbughttps://wiki.haskell.org/index.php?title=Haskell_Tutorial_for_C_Programmers&diff=58049Haskell Tutorial for C Programmers2014-05-09T21:22:23Z<p>Heisenbug: </p>
<hr />
<div>Haskell Tutorial for C Programmers, by Eric Etheridge<br />
<br />
version 3.0 - please increment with major updates<br \><br />
original author: Eric Etheridge<br \><br />
last major update by the original author: August 28, 2011<br \><br />
year of original release (on old haskell.org site): 2005<br />
<br />
__TOC__<br />
<br />
==Introduction==<br />
<br />
===Abstract===<br />
<br />
Many people are accustomed to imperative languagues, which include C, C++, Java, Python, and Pascal. For computer science students, Haskell is weird and obtuse. This tutorial assumes that the reader is familiar with C/C++, Python, Java, or Pascal. I am writing for you because it seems that no other tutorial was written to help students overcome the difficulty of moving from C/C++, Java, and the like to Haskell.<br />
<br />
I write this assuming that you have checked out the Gentle Introduction to Haskell, but still don't understand what's going on.<br />
<br />
Haskell is not 'a little different,' and will not 'take a little time.' It is very different and you cannot simply pick it up, although I hope that this tutorial will help.<br />
<br />
I am going to put many pauses in this tutorial because learning Haskell hurt a lot, at least for me. I needed breaks, and my brain hurt while I was trying to understand.<br />
<br />
Haskell has both more flexibility and more control than most languages. Nothing that I know of beats C's control, but Haskell has everything C does unless you need to control specific bytes in memory. So I call Haskell powerful, rather than just 'good.'<br />
<br />
I wrote this tutorial because Haskell was very hard for me to learn, but now I love it. &quot;Haskell is hard!&quot; &quot;You can't write code the way I know how!&quot; &quot;My brain hurts!&quot; &quot;There aren't any good references!&quot; That's what I said when I was in college. There were good references, but they didn't cover the real problem: coders know C.<br />
<br />
This abstract was pieced together by Mark Evans, [http://lambda-the-ultimate.org/node/view/724 here], from my own work. I have had no contact with Mark Evans, but since he did't contact me when he editted together this abstract from my work and posted it on lambda-the-ultimate, I doubt he'll care that I've taken that edit and used it as my abstract here. If he wishes, he may contact me regarding the legal status of this work. For now, I assume I still hold the copyright on all of it, including the abstract (released in [http://haskell.org/haskellwiki/HaskellWiki:Copyrights the license for this site]).<br />
<br />
<br />
===Downloads===<br />
<br />
In the former form of this tutorial, I had a zipped version of the html files available at this point. However, this wiki provides a "printable version" button and the tutorial is now be one long page (which may be a poor design choice, we'll see). In addition, a bundled version might quickly become out of date from minor corrections by site patrons. Therefore, it doesn't seem necessary at the moment to include a zipped bundle of the tutorial text.<br />
<br />
Here are the source files and text for all examples for this tutorial, including all those in the sections and the large examples at the end, zipped using bzip2: [[Media:HaskellForC_Examples.tar.bz2|bzip2 of sources, 28K]], and zipped as a zip: [[Media:HaskellForC_Examples.zip|zip of sources, 43K]].<br />
<br />
Sources for the in-text examples in the coming sections are given in the following files:<br />
* ExampleSectionsCode.hs<br />
* ExampleSectionsTry.txt<br />
<br />
If you don't have bzip2, you can get the latest version at [http://www.bzip.org/ www.bzip.org].<br />
<br />
<br />
===License===<br />
<br />
The original form of the tutorial was available under a Creative Commons License, specifically Attribution-Share Alike 3.0. That license still applies to any form downloaded or read while that version was available. This wiki requires submitted work to be subject to a specific license, so this work is now available under this [http://haskell.org/haskellwiki/HaskellWiki:Copyrights simple permissive license]. I would still prefer some attribution if the work was used wholesale.<br />
<br />
<br />
===This Tutorial's Purpose and Other Online References===<br />
<br />
Many people are accustomed to imperative languagues, which include C, C++, Java, Python, and Pascal. In fact, most languages in common usage are imperative, other than LISP, Scheme, ML, and OCaml. For computer science students in high school or early college, it is virtually guaranteed that Haskell is weird and obtuse. I first encountered Haskell in the classroom when I was a freshman at UT Austin, and then in another class at UT two years later. I was only familiar with C/C++, Pascal, and QBASIC, and all of the Haskell tutorials and books seemed to assume more of my education. This tutorial assumes that the reader is familiar with C/C++, Python, Java, or Pascal. This tutorial is specifically for '''students''' of computer science, people in their first few years of college, or even in high school. I am writing for you because it seems that no other tutorial was written to help students overcome the difficulty of moving from C/C++, Java, and the like to Haskell.<br />
<br />
====GHC and Hugs====<br />
<br />
To learn and use Haskell, you should install GHC, and perhaps Hugs. GHC is the "de facto standard" compiler for Haskell, and almost all projects in Haskell use it. The Hugs interpreter is a simpler tool that will let you play around and learn. Start with Hugs if you are having trouble using GHC. GHC also ships with GHCi, "GHC interactive", which is a command line interpreter much like Hugs, but no GUI. Getting these programs is easy. If you use Debian, GHC and Hugs are packages. For everyone else, the homepages are here:<br />
<br />
[http://www.haskell.org/ghc/ http://www.haskell.org/ghc/]<br />
<br />
[http://www.haskell.org/hugs/ http://www.haskell.org/hugs/]<br />
<br />
====The Gentle Introduction to Haskell====<br />
<br />
I write this assuming that you have checked out the following tutorial, the Gentle Introduction to Haskell, but found that you still don't understand what's going on:<br />
<br />
[http://www.haskell.org/tutorial/ http://www.haskell.org/tutorial/]<br />
<br />
====Tour of the Haskell Syntax====<br />
<br />
The Gentle Introduction to Haskell is a good reference for basic syntax. In this tutorial we will skip most syntax details until later. First we will cover defining functions in Haskell and why it is central to the language. For more syntax details, here is another tutorial, the Tour of the Haskell Syntax, which has much more specific information:<br />
<br />
[http://www.cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html http://www.cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html]<br />
<br />
You should look through the Tour, since it describes the appropriate syntax for most of the things I discuss. The Tour is useful because you can understand it without knowing everything about Haskell. Reading these can help you before, after, or during this tutorial.<br />
<br />
====The Prelude File====<br />
<br />
One of the best references is the source code for the Prelude, which is the file &quot;Prelude.hs&quot;. This file holds the code for all of the general-purpose functions in the Prelude module. If any function shows up that you don't understand, you can look up its definition in source code and figure out what it's really doing. This is a very good practice for those unfamiliar with general Haskell use.<br />
<br />
There are (at least) three ways to get a copy of the Prelude.hs file. If you download and install Hugs, Prelude.hs will be in the libraries directory. I do not think that GHC ships with the uncompiled library sources. You can download a source version of GHC from its download page. You may be able to find a gzipped copy in the ghc "libsrc" Debian package.<br />
<br />
====GHC Hierarchical Libraries====<br />
<br />
Another important resource is the GHC Hierarchical Libraries documentation. The data types and functions of every module are defined here, including the Prelude. Whenever you use a library function, you'll want to refer to these to find the module and specific usage. All the standard modules are well documented. If your GHC installation includes the docs, these webpages are also on your local machine.<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/index.html http://www.haskell.org/ghc/docs/latest/html/libraries/index.html]<br />
<br />
====Monads for the Working Haskell Programmer====<br />
<br />
When I was working on the large examples that included monads, I used a lot of help from here:<br />
<br />
[http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm]<br />
<br />
<br />
===Preface and Style Notes===<br />
<br />
I am not writing a Haskell reference. This is a tutorial designed to take someone having trouble understanding Haskell and help them. This tutorial is for people who, like me, needed to learn enough concepts to understand the code covered in a classroom. Haskell allows things to be done easily and clearly, but it is not easy or clear, and it can be extremely challenging for a novice. You cannot pick up Haskell code and understand it. What I have attempted to write is a tutorial that covers the common aspects of Haskell that are the most obtuse.<br />
<br />
As the tutorial progresses, one thing should become clear about Haskell: its real power comes into play when you attack difficult problems. Because of this, I use some difficult problems in this tutorial. Don't worry if you don't understand the solutions after reading the tutorial once. Haskell is not a toy language, and even a moderately sized set of functions will include several of Haskell's complicated tools all working together. This has left educators with a dilemma: do I use ridiculously simple code in order to cover a single topic at once, or do I use something actually useful and try to explain all the pieces and how they all fit together? Many tutorials and lessons have chosen the former, but I prefer the latter. That means that each example requires a lot of explaining. Often concepts must be explained once in extremely simplistic terms, and then explained again later after other related topics have also been briefly discussed. As you read this tutorial, remember this: Haskell's real power is the fact that all of its pieces fit so well together, not just that they are good pieces.<br />
<br />
The syntax and variable name conventions I use in this tutorial are those used in the Haskell source code and libraries, and what I learned in college. Haskell programs tend to be short, but wide. I recommend using descriptive variable names, even for indices and so forth.<br />
<br />
<br />
==Section I: What the Heck is Going On?==<br />
<br />
===Part I: Haskell's Oddity===<br />
<br />
To begin, Haskell has no update operator. If that sentence did not make sense, then please keep reading, because this tutorial was written with you in mind. By 'update operator', I mean that the following does not happen in normal Haskell:<br />
<br />
int a<br />
a := 4<br />
print a<br />
a := 5<br />
print a<br />
<br />
> 4<br />
> 5<br />
<br />
The above programming style, i.e. 'making a variable, putting data in it, using it, then replacing the data in it, using it again' does not happen in normal Haskell. Those of you who have used LISP or Scheme will be familiar with this concept, but I am sure that the rest of you are probably baffled. Here is how Haskell works, again in pseudo-code:<br />
<br />
print a<br />
<br />
int a<br />
a = 5<br />
<br />
> 5<br />
<br />
or<br />
<br />
int a<br />
a = 5<br />
<br />
print a<br />
<br />
> 5<br />
<br />
The order of these actions does not matter. There is also a reason that the first example used ':=' and the second example used '='. In 'imperative' languages, storing data is an operation, and it happens in a sequence. In 'functional' languages like Haskell, the equal sign means an exact definition. In other words, each variable is equal to its value not only after the assignment statement is reached in sequence, but in fact at all points during execution.<br />
<br />
Some of you may be saying, &quot;That's nice, Eric, but what good is a language where everything is hardcoded? Wouldn't I have to define every variable with its correct value as I coded? Isn't 'computing' values the whole point of a 'computer'?&quot; And you would be right; knowing results ahead of time would make computing weird. The 'redeeming' feature of Haskell is that you don't need to store data to return a result.<br />
<br />
I am going to put many pauses in this tutorial because learning Haskell hurt a lot, at least for me. I needed breaks, and my brain hurt while I was trying to understand. Let's look at that statement again: you don't need to store data to return a result. I'll illustrate. Here is an example of a function in C:<br />
<br />
int foo (int bar) {<br />
int result;<br />
result = bar * 10 + 4;<br />
return result;<br />
}<br />
<br />
The important part is the expression in the middle. It can also be written as follows:<br />
<br />
int foo (int bar) {<br />
return bar * 10 + 4;<br />
}<br />
<br />
These are the same, but the second is shorter and clearer. With a function like this, you could state the following: &quot;The value of foo(x) is equal to (x * 10 + 4).&quot; Or, more simply, &quot;foo(x) = x * 10 + 4&quot;. I know you're saying, &quot;Most functions aren't that simple.&quot; That is true, but bear with me. Haskell has much more powerful tools for writing functions than most other languages, and a lot of complicated operations look this simple in Haskell. The key to using those tools will be changing the way you think from '''<nowiki>'make data, then alter it'</nowiki>''' to '''<nowiki>'define a function that would return the result, then apply to inputs'</nowiki>'''.<br />
<br />
<br />
===Part II: Input and Output===<br />
<br />
We'll come back to the frame of mind later. There is such a difference between Haskell and C/C++ that many concepts only make sense in conjunction with others. I need to cover the basics of several concepts before I can explain each of them fully.<br />
<br />
Moving on, the question on everybody's mind is probably either, &quot;How does I/O work?&quot; or &quot;What are these tools?&quot; IO is one of the complicated parts of Haskell, and later I'll describe how it works. I will also describe a simple frame for programming with GHC. Until then, use GHCi or Hugs to try the examples. They have an interactive prompt where you type in expressions, like a function plus its parameters. Then they print the evaluated result. Also, variable bindings such as 'a = 4' hang around while you're using Hugs and GHCi, so my examples should work just fine. To write your own functions, you need to write a Haskell source file and load it first. Using GHC itself requires knowing some of Haskell's more complicated tools, so we'll put off learning those until we need GHC.<br />
<br />
To use Hugs and GHCi with your own functions, you have to write a Haskell source file and load it into the interpreter. Generally, this works as follows:<br />
<br />
# Open a text editor and write Haskell code.<br />
# Save that code as a file with the extension '.hs', for instance, 'test.hs'.<br />
# With the source file in the current directory, run Hugs or GHCi.<br />
# In Hugs or GHCi, at the prompt type ':l test.hs'. That's a lowercase 'L'.<br />
# Source code that needs modules, say Data.Maybe, should include 'import Data.Maybe' at the top.<br />
<br />
Note that the module 'Prelude' is automatically imported. The Prelude module covers most basic elements of the language.<br />
<br />
<br />
===Part III: Very Basic Intro to Types===<br />
<br />
Moving on again, let's talk about tools. Haskell's greatest strength lies in the power a programmer has to define useful functions easily and clearly. Here is our earlier example from C:<br />
<br />
int foo (int bar) {<br />
return bar * 10 + 4;<br />
}<br />
<br />
In Haskell, to write this function named foo, you would write the following:<br />
<br />
foo bar = bar * 10 + 4<br />
<br />
That's all, except for the type:<br />
<br />
foo :: Int -&gt; Int<br />
<br />
The type reads, &quot;foo is of type Int to Int&quot;, meaning that it takes an Int and returns an Int. Together, you write:<br />
<br />
foo :: Int -> Int<br />
foo bar = bar * 10 + 4<br />
<br />
Defining functions and types is the majority of the work in Haskell, and usually they require equal amounts of time. Haskell has a variety of ways to define functions. I feel that the tutorials mentioned previously do not adequately introduce these ways, so we will discuss them in detail later once we have some tools under our belt.<br />
<br />
<br />
===Part IV: Haskell's Lists and List Comprehensions===<br />
<br />
Those of you familiar with C know that pointers are the primary object in the language. For almost all imperative languages, the most useful structure is the Array, a randomly accessible sequence of values usually stored in order in memory. Haskell has arrays, but the most-used object in Haskell is a List. A list in Haskell is accessible only at the front, and is not stored in order in memory. While this may sound atrocious, Haskell has such weird abilities that it is more natural to use a list than an array, and often faster. Let us start with the C code to compute the fibonacci numbers (starting with zero):<br />
<br />
int fib (int n) {<br />
int a = 0, b = 1, i, temp;<br />
for (i = 0; i < n; i++) {<br />
temp = a + b;<br />
a = b;<br />
b = temp;<br />
}<br />
return a;<br />
}<br />
<br />
This is fine for computing a particular value, but things get ugly when you want to create the sequence:<br />
<br />
int * fibArray(int n) {<br />
int * fibs;<br />
fibs = (int *)malloc((sizeof int) * n);<br />
for (i = 0; i < n; i++) {<br />
fibs[i] = a;<br />
temp = a + b;<br />
a = b;<br />
b = temp;<br />
}<br />
return fibs;<br />
}<br />
<br />
When I say 'get ugly', I mean that something is included in that function which shouldn't be there: the size of the list. The fibonacci sequence is infinite, and the code above does not represent it, only a part of it. This doesn't sound so bad, unless you don't know how many values you need initially.<br />
<br />
In Haskell, 'fib', the function to compute a single fibonacci value, can be written as follows:<br />
<br />
fib :: Int -> Int<br />
fib n = fibGen 0 1 n<br />
<br />
fibGen :: Int -> Int -> Int -> Int<br />
fibGen a b n = case n of<br />
0 -> a<br />
n -> fibGen b (a + b) (n - 1)<br />
<br />
This is a slight improvement over the C code, but not much. Note that the type of fibGen is &quot;Int to Int to Int to Int&quot;, meaning that it takes three Ints and returns an Int. More on that later. Also note that this uses a recursive function. Recursion is everywhere in Haskell. Most of your 'looping' functions will involve recursion instead.<br />
<br />
The real improvement over C comes in defining the sequence:<br />
<br />
fibs :: [Int]<br />
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]<br />
<br />
Don't be scared. Once you understand this function, you will understand at least half of the intracies of Haskell. Let's take it from the top. In Haskell, lists are written as follows:<br />
<br />
[ 4, 2, 6, 7, 2 ]<br />
<br />
This is the list of 4, then 2, then 6, etc. The ':' operator is used to compose a list by sticking a value on the front (left). For instance: <hask>temp = 1 : [ 4, 2, 5 ]</hask> is the list [ 1, 4, 2, 5 ].<br />
<br />
That means that in the above code, fibs is a list of Int, and its first two values are zero and one. That's good so far. At least the first two values of 'fibs' will be right. The next part definitely looks weird. It's a tool found in Haskell called a 'list comprehension'. In Part II, I said that instead of making space and then filling it with the right values, you can define the right values. Here's that sentence, restated for list comprehensions: &quot;You can define the values of the list rather than make space and then fill them in.&quot; List comprehensions work like so:<br />
<br />
[ func x | x <- list, boolFunc x ]<br />
<br />
This expression makes a new list. In the middle, there's a 'list', and it spits out values called x. These are the values of the list in order. If 'boolFunc x' is True, then x will get used in this new list. No boolFunc is in the 'fibs' example, but I include it here because it can also be extremely handy. Assuming 'boolFunc x' was true, 'func x' applies some function to the value of x, and the result is then put next in line in the final result. Here's an example of a list and its use in some list comprehensions, copied from using GHCi:<br />
<br />
Prelude&gt; let nums = [ 4, 2, 6, 8, 5, 11 ]<br />
Prelude&gt; [ x + 1 | x &lt;- nums ]<br />
[5,3,7,9,6,12]<br />
Prelude&gt; [ x * x | x &lt;- nums, x &lt; 7 ]<br />
[16,4,36,25]<br />
Prelude&gt; [ 2 * x | x &lt;- 9 : 1 : nums ]<br />
[18,2,8,4,12,16,10,22]<br />
Prelude&gt; [ "String" | x &lt;- nums, x &lt; 5 ]<br />
["String","String"]<br />
Prelude&gt;<br />
<br />
Note that the order was preserved in each case. This is very important for our example. Also note that the type of the list comprehension was not necessarily the type of nums, nor did x actually have to be used in the function. Let's return to 'fibs'.<br />
<br />
<br />
===Part V: Making Sense of 'fibs', and Why Lazy Evaluation is Important===<br />
<br />
We were working on a definition for the list of Fibonacci numbers. Here is the example again:<br />
<br />
fibs :: [Int]<br />
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]<br />
<br />
So what the heck is '(a, b)' and 'zip fibs (tail fibs)' and all that? Well, Haskell has a more expressive type system than most other languages. As in Python, '(a, b)' is a tuple, meaning two values stuck together. It's a convienent way to store and pass multiple values, much more so than structs. Just add parentheses and enough commas, and you pass the group of values around as you please. The only trick is that Haskell expects you to be consistent, and that means having the right type. The code adds 'a' and 'b' together to get a number in the Fibonacci sequence, so we know that'a' and 'b' are integers. Clearly, '(a, b)' is of type '(Int, Int)', which is stated as follows:<br />
<br />
(a, b) :: (Int, Int)<br />
<br />
We get these values labeled '(a, b)' from the list defined by 'zip fibs (tail fibs)'. Therefore 'zip fibs (tail fibs)' is of type '[(Int, Int)]', a list of 2-tuples of an Int and an Int. More clearly:<br />
<br />
zip fibs (tail fibs) :: [(Int, Int)]<br />
<br />
You can use GHCi and Hugs to print these types. The ':t' command, followed by a variable or function, will print its type. The following is at the GHCi prompt with the example file that includes the fibs function loaded:<br />
<br />
*Main&gt; :t zip fibs (tail fibs)<br />
zip fibs (tail fibs) :: [(Int, Int)]<br />
*Main&gt;<br />
<br />
So what is 'zip'? Its type and general meaning are given here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:19 The Prelude, section: Zipping and Unzipping Lists]<br />
<br />
'zip', as its name somewhat implies, takes two lists and 'zips' them together, returning a list of tuples, with the left member of each tuple being an item from the first (left) list, and likewise for the right.<br />
<br />
Prelude&gt; zip [ 1, 3, 6, 2 ] [ "duck", "duck", "duck", "goose" ]<br />
[(1,"duck"),(3,"duck"),(6,"duck"),(2,"goose")]<br />
Prelude&gt;<br />
<br />
And what about '(tail fibs)'? 'tail' is a pretty straightforward function: it chops off the first item of a list and returns the remainder. That statement can be slightly misleading. 'fibs' doesn't get altered by using 'tail' on it; as I said before, Haskell doesn't have an update operation. Instead, 'tail' just computes the proper result and returns it, rather than altering 'fibs' itself.<br />
<br />
Prelude&gt; tail [ 10, 20, 30, 40, 50 ]<br />
[20,30,40,50]<br />
Prelude&gt;<br />
<br />
Well, that makes it seem like 'zip fibs (tail fibs)' probably has the right type, but what is it?<br />
<br />
fibs :: [Int]<br />
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]<br />
<br />
The first paramater to zip is 'fibs', which is the list defined by the expression! What the heck? Can you do that? Yes, you can. See, 'fibs' is the entire list, including the 0 and 1 at the beginning. So the first two tuples in the list created by the zip function will have a 0 and then a 1 on their left. So what is 'zip fibs (tail fibs)'? Well, the first value is definitely (0, 1). Why? Because the first item in fibs is 0, and the first item in (tail fibs) is 1, the second item in fibs. So what's the second value in zip fibs (tail fibs)? It's (1, 1). Where did the right hand 1 come from? It's the third value in fibs, which we just computed. The first value of zip fibs (tail fibs) is (0, 1), which is '(a, b)' in the list comprehension, and so the first value in that comprehension is 0 + 1, or 1. That is also the third value in fibs, etc.<br />
<br />
Did you catch all that? The definition of fibs is evaluating itself while it is computing itself. So why didn't some sort of error happen because of undefined values? The trick to all of this is Haskell's laziness. Also, the evaluation is always one step behind the computation, so evaluation can always proceed exactly as far as needed for the next computation. Finally, this list is infinite. Of course, no computer can hold an infinite amount of data. So how much is really there? The answer is simple: until you read some values from fibs and print them, there's only the 0 and the 1, plus the function to generate more of the list. After you read some, fibs will be evaluated to that point, and no further. Since fibs is defined globally, it will remain defined in memory, making reading further values very quick. Try this with Hugs or GHCi and you see'll what I mean.<br />
<br />
fibs !! 2<br />
fibs !! 4<br />
fibs !! 30<br />
fibs !! 30<br />
fibs !! 6<br />
fibs !! 20<br />
fibs !! 30<br />
take 10 fibs<br />
<br />
'!!' is the 'index' operator for lists in Haskell. It walks down the list and returns the nth item, zero-indexed like C/C++ and Python. 'take 10 fibs' will return the first 10 values of fibs. Be careful, fibs has infinite length. If you just type 'fibs', the output could go forever.<br />
<br />
And why does the list only get evaluated as far as you print it? Haskell is 'lazy', meaning that it doesn't do work that it doesn't have to. C programmers know that the boolean operators '&amp;&amp;' and '||' are 'short-circuit', meaning that the right hand side is not evaluated unless it's needed. This allows for all kinds of neat tricks, like not dereferencing a null pointer. '''The entire language of Haskell has this short-circuit behavior, including the functions that you write yourself.''' This sounds strange, and will become even more important when we get to Haskell's tools.<br />
<br />
This also brings us to one of the other odd things about Haskell: '''It is often easier to code the general definition for something than to write a function that generates a specific value.''' This is one of those things you have to get used to, and you will probably come back to it again. And again.<br />
<br />
Well, give yourself a pat on the back. If you got all that, or at least you will after playing around in Hugs, then you understand about half of the common usages of Haskell. Ready for the other half? Maybe take a break, and play around a bit in Hugs or GHCi.<br />
<br />
<br />
==Section II: Towards Functions==<br />
<br />
===Part I: The Order of Operations as a Programmer===<br />
<br />
A programming note for recursive functions and Haskell:<br />
<br />
Concerning the fib / fibGen example here:<br />
<br />
fib :: Int -> Int<br />
fib n = fibGen 0 1 n<br />
<br />
fibGen :: Int -> Int -> Int -> Int<br />
fibGen a b n = case n of<br />
0 -> a<br />
n -> fibGen b (a + b) (n - 1)<br />
<br />
When I was writing this example, I wrote the type of fib first, then the type and definition of fibGen, then finally the definition of fib.<br />
<br />
For those of you who are not accustomed to writing recursive functions, Haskell programming often requires them. Often these recursive functions need subsidiary functions, which either 'frame' the main operation of recursion, or perform a simple task that keeps the main recursion function clean. In either case, the subsidiary functions can be written later, after the major recursive operation is clearly defined including end conditions.<br />
<br />
In general, it is a good idea to concentrate on the most crucial aspect of a piece of code when programming, but Haskell's design greatly reinforces this. The definition of subsidiary functions, such as the 'setup' where fib calls fibGen with parameters '0 1 n', can wait until the function itself has been written. This is true even though the type of fib was obvious from the beginning. Likewise, Haskell makes writing trivial functions like that so quick that they can generally be ignored while thinking about the larger picture. These things are likely to change the way that you code, and probably in a good way.<br />
<br />
<br />
===Part II: Functions, But Really a Sidetrack to Types===<br />
<br />
As we move on, the other half of Haskell's general usage looms. This half is about functions.<br />
<br />
So what is a function? As this tutorial's alignment indicates, we'll compare C/C++ to Haskell. In C, a function is a sequence of commands that have their own namespace, are called during execution and passed parameters, inherit the namespace of the scope in which they are written, and return a value to their caller. In Haskell, most of that is true, except of course functions in Haskell are not sequences of events, but expressions and definitions. There is a major difference between C and Haskell, however, and it concerns the amount of flexibility that functions have.<br />
<br />
In C, functions take parameters and return a single value. We've already seen that Haskell has many ways to group values, like several other languages. The two most common of these are lists and tuples, and these can be the return type from a function. To sum them up, in Haskell lists are variable length and hold values of the same type, and tuples are fixed length and can hold values of different types. Here is an example of a function type that returns a tuple:<br />
<br />
splitAt :: Int -> [a] -> ([a], [a])<br />
<br />
'splitAt' takes an Int and a list and returns a tuple. The left value in the tuple is the first n values in the list, and the right value is the rest of the list, where n is the first parameter. This function is in the Prelude, and its description can be found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:17 The Prelude, section: Sublists]<br />
<br />
We've already seen lists in a type:<br />
<br />
fibs :: [Int]<br />
<br />
Since the fibonacci numbers grow rapidly, but 'Int' is 32-bit, it would probably have been better to use 'Integer', Haskell's built-in infinite-precision integer storage.<br />
<br />
fibs :: [Integer]<br />
<br />
And this is a function type. The function takes zero parameters and returns a list of Integers. This isn't a trick of Haskell's syntax. 'fibs' really is a function that, <i>when evaluated</i> will return numbers comprising the fibonacci sequence. That kind of logic is what lets Haskell's compilers produce code which runs quickly and lets Haskell programmers write code efficiently.<br />
<br />
<br />
===Part III: More Types, Because Haskell Is 'Polymorphic'===<br />
<br />
It's time for a brief <nowiki>[not so brief]</nowiki> digression about types. As you've noticed, the trend seems to be to call everything a 'function'. And that's true. Take '4' for example. When you use a number '4' hardcoded into your code, it looks to you like the number 4. But what is it to Haskell? Type ':t 4' into Hugs or GHCi. What do you get? You get some weird junk:<br />
<br />
Prelude&gt; :t 4<br />
4 :: (Num t) => t<br />
Prelude&gt;<br />
<br />
That looks like it's a function that's taking a parameter. It's not, and the key is the '=&gt;' arrow rather than the '-&gt;' arrow. The type given is read as follows: &quot;four is of type 't', where 't' is in the class 'Num'.&quot; What's the class 'Num'? Well, it's the class that all numbers belong to. The real answer is that Haskell has something C doesn't: '''true polymorphism'''.<br />
<br />
This is an important term and it needs some illustration. Most C++ programmers are familiar with the term 'overloading', which means that a function is defined for more than one set of parameter types. For instance, addition and multiplication in C/C++ are overloaded, allowing the following combinations to occur:<br />
<br />
int a = 4, b = 5;<br />
float x = 2.5, y = 7.0;<br />
<br />
cout << a + b; //9<br />
cout << a + y; //11<br />
cout << y + a; //11.0<br />
cout << x + y; //9.5<br />
cout << b * a; //20<br />
cout << b * x; //12.5<br />
cout << y * b; //35.0<br />
cout << x * y; //17.5<br />
<br />
In C/C++, this is accomplished by defining all of the following overloaded definitions for '+' and '*':<br />
<br />
operator+ (int, int);<br />
operator+ (int, float);<br />
operator+ (float, int);<br />
operator+ (float, float);<br />
operator* (int, int);<br />
operator* (int, float);<br />
operator* (float, int);<br />
operator* (float, float);<br />
<br />
The C compiler picks the appropriate type at compile time. The key distinction between polymorphism and overloading is that in C/C++, which uses overloading, each function above must be written separately. In C/C++, any function besides those above that uses either an int or a float must specify which one it expects, or must ''itself'' be overloaded. This bring us to the idea of classes.<br />
<br />
For what types is '+' defined in C/C++? It is possible to overload the operator for new types defined by a user, but those new types will not be interchangeable with ints, floats, or other numeric types. What this means is that existing sort functions such as mergeSort and quickSort would need to be rewritten to sort values of the new type. In constrast, here is the type of mergeSort in Haskell:<br />
<br />
mergeSort :: Ord a => [a] -> [a]<br />
<br />
What is going on? Again, there are two parameters listed, not three. The first thing that appears to be a parameter is actually a class restriction. 'mergeSort', as you would expect, takes a list of objects of some type (type 'a'), and returns a list of objects of the same type. So why is the following type not sufficient?:<br />
<br />
mergeSortBadType :: [a] -> [a]<br />
<br />
The reason this is insufficient is that at some point in mergeSort the items in the list will need to be compared to each other. This will be done using a comparison operator such as '&gt;', '&lt;', '&gt;=', or '&lt;='. In Haskell, those operators are part of a class definition. The values for which '&gt;' and so on are defined are those which are members of class 'Ord', so named because an 'order' can be determined for them. Many numeric types are of type Ord, as are characters (type 'Char') and strings (type 'String'). mergeSort needs to compare the items in its inputs, so mergeSort must clarify its type. Its parameter must be a list of objects for which '&lt;' and so on are defined. It would also be okay to make the type more specific, but this is unnecessary and generally a bad technique.<br />
<br />
And what about '4'? How come four is of type 'a', where 'a' is a member of class 'Num'? Can't it just be a Num? Or an Int? It can be an Int if we specifically say it is, like so:<br />
<br />
a = (4 :: Int) + 2<br />
<br />
Here '4' is an Int. That is how you specify the type of something inside of an expression. But without that, 4 is of type 'a', where 'a' is in class 'Num', or more simply, 4 is of type 'a' in class 'Num'. And that is important, because '+' is defined for all member types of class Num, meaning that '4' is definitely a legal parameter for this function:<br />
<br />
doubleIt :: Num a => a -> a<br />
doubleIt n = n + n<br />
<br />
'-' and '*' are also defined for all member types of Num, so 4 is also allowed for this function:<br />
<br />
fibPoly :: (Num a, Num b) => a -> b<br />
fibPoly n = fibGenPoly 0 1 n<br />
<br />
fibGenPoly :: (Num a, Num b) => b -> b -> a -> b<br />
fibGenPoly a b n = case n of<br />
0 -> a<br />
n -> fibGenPoly b (a + b) (n - 1)<br />
<br />
That is our first Haskell fib function, but with the types changed. The names have an added 'Poly' so that an error doesn't occur in the example files because of a reused name. The type of 'fibPoly' is read, &quot;fibPoly is of type 'a' to 'b', where 'a' is a member of class Num and 'b' is a member of class Num.&quot; There is only one '=&gt;' arrow because there is only ever one section of the type that describes class restrictions. The parentheses are required.<br />
<br />
Why would we do this? Shouldn't we pick a single type for b rather than use a class? Here's an example. What if you worked on a group project, and two people need to calculate fibonacci numbers? And for reasons of their own, one needed an Int returned and the other needed an Integer? Or a Double? Would you write the code twice with different types? If you were using C you would. You'd have to. Using general type classes allows code reuse in a way that is impossible in other languages.<br />
<br />
Also notice that in the initial call to 'fibGenPoly', the third parameter is 'n', the first parameter of 'fibPoly', and that the types of 'fibPoly' and 'fibGenPoly' seem to make note of this. The reason I wrote 'fibPoly' with a different return type from its parameter is that the following would be common:<br />
<br />
fib :: Int -> Integer<br />
<br />
We only need Int-sized storage of our counter input, but we may need Integer-sized storage of the result. Using two separate types allows this. Also, carefully check how types flow in 'fibGenPoly'. The math does not mix parameters of type 'a' and 'b', and a parameter of type 'b' is also used as the final return value. The types match not only externally but internally. Following types through code in this manner will be important for debugging.<br />
<br />
Continuing onward, in the fib example we used 'tail'. Here is its type:<br />
<br />
tail :: [a] -> [a]<br />
<br />
In C, tail would have to be reimplemented for every type of list you used. That sounds like a slightly contrived problem, so what about '!!', the index operator? In most other languages, indexing a list is a built-in operator, because it has to work for every kind of array. So it's not actually a function. And so on. Everything in C is either overloaded, built in, or works for only one type. There are a few exceptions, generally involving casting to or from '(void *)', but those are far outside the scope of this tutorial.<br />
<br />
The point is, you're going to see 'Num a =&gt;' at the beginning of type signatures, as well as 'a' and 'b' inside type signatures. Here, 'a' and 'b' are type variables, used by the compiler solely to determine proper types for compilation. Occasionally you will get messages such as 'can't determine type', or 'type mismatch'. The second means the you've done something wrong, but the first usually means that a type variable can't be pinned down to a single type for a function that you've written. This can happen for the simplest of reasons:<br />
<br />
main = putStrLn (show 4)<br />
<br />
Previous versions of GHC would not accept this. Here's why: 'putStrLn' takes a string and puts it on the screen. 4 has a 'polymorphic' type, i.e. it is a member of a type class, not defined as a specific type. 'show' takes anything that can be turned into a string (basically), and so it doesn't specify a type for '4' either. This leaves the compiler in a quandry, because no specific type is indicated anywhere, and it will complain. To resolve it, add the type definition like so:<br />
<br />
main = putStrLn (show (4 :: Int))<br />
<br />
Or Integer, or Double, or whatever. This will be handy when you try to test generalized functions, and you'll need it in a few other weird cases as well.<br />
<br />
One last note. You can define the type of multiple functions simultaneously:<br />
<br />
addOne, subtractOne :: Int -> Int<br />
<br />
This can be handy.<br />
<br />
===Part IV: Functions Already===<br />
<br />
But we were talking about functions. As you may have noticed, it seems like anything can work as a parameter or return value for a function. This is absolutely true, as long as the types match. For instance, let's take a look at the extremely useful 'map' function:<br />
<br />
map :: (a -> b) -> [a] -> [b]<br />
<br />
By now you can probably read that, strange as it may be. &quot;map is of type function a to b followed by a list of type a and returns a list of type b&quot;. It's taking a function as a parameter. Not only that, but a polymorphic function, with no type restrictions. And look at the other two items. The function it takes is from a to b, and then it takes a list of type a and returns a list of type b. With a name like 'map', it's pretty clear what should happen when you use it:<br />
<br />
fooList :: [Int]<br />
fooList = [3, 1, 5, 4]<br />
<br />
bar :: Int -&gt; Int<br />
bar n = n - 2<br />
<br />
*Main&gt; map bar fooList<br />
[1,-1,3,2]<br />
*Main&gt; <br />
<br />
Nothing to it. In the past a type for at least 'fooList' or 'bar' would have been required or Hugs and GHC would have complained that the types could not be fully determined. 'map' is in the Prelude, and its description can be found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:11 The Prelude, section: List Operations]<br />
<br />
The example using 'map' shows that you can write functions which take functions as parameters. This can be fun and very useful. Now let's try something stranger:<br />
<br />
subEachFromTen :: [Int] -> [Int]<br />
subEachFromTen = map (10 -)<br />
<br />
What the heck? First, for this to work there do need to be parentheses around the '-' and the '10'. Second, what does this do? We'll take this one step at a time again. '(10 -)' is a function. It takes a number and returns ten minus that number. Use ':t' in Hugs or GHCi to find out its type:<br />
<br />
*Main&gt; :t (10 -)<br />
(10 -) :: (Num t) => t -> t<br />
*Main&gt;<br />
<br />
Second, 'map' takes a function as its first parameter. There's a reason that Haskell uses arrows to define types, rather than a parenthesized list. 'map', applied to '(10 -)' has the following type (again, check in Hugs and GHCi):<br />
<br />
*Main&gt; :t map (10 -)<br />
map (10 -) :: (Num t) => [t] -> [t]<br />
*Main&gt; <br />
<br />
It takes a list of Num members (all the same type of Num members, mind you) and returns a list of the same type (again, the same type member of Num). This is constrained to [Int] -> [Int] by subEachFromTen's type signature. Applying the 'map' function to less than its full list of arguments like this is called 'partial evaluation'. You take a function, give it some of its parameters, and you've got a function that takes the rest of the parameters. You can even name this 'in-between' state, since it is just a function like anything else. Here is 'subEachFromTen' in action:<br />
<br />
*Main&gt; subEachFromTen [4, 6, 7, 11]<br />
[6,4,3,-1]<br />
*Main&gt;<br />
<br />
It does what you think it should, given how I named it. Remember that applying subEachFromTen to a list, even a named list, does not change that list, but merely returns the result.<br />
<br />
Take some time now to play around with partial evaluation, in addition to the list functions mentioned before and list comprehensions. Remember that functions grab their parameters 'eagerly', so you have to put parentheses around any parameters that are composed of a function with its own parameters.<br />
<br />
<br />
==Section III: Now Let's Really Write Functions==<br />
<br />
===Part I: Did You Take That Break? Here Are Patterns===<br />
<br />
Hopefully you are now comfortable defining and using functions in Haskell using your choice of Hugs, GHC, or GHCi. Now it's time to talk about all the ways in which functions can be defined. If you are not ready, re-read some of the earlier material and set up one of the programs for using Haskell. The rest of this will only help you if you're trying it for yourself.<br />
<br />
Each function has a type. Even functions with no parameters each have a type, i.e. global and local variables. It is not always necessary to write this type, as Haskell compilers can determine it. However, writing it is a good practice and sometimes a necessity. We are about to cover a lot of syntax, so after reading this section, it would be a good idea to read the Tour of the Haskell Syntax listed in the introduction.<br />
<br />
There are a few examples we can go through to make that page clearer. First, a simple function that walks down a list and sums its members:<br />
<br />
sumAll :: Num a => [a] -> a<br />
sumAll (x:xs) = x + sumAll xs<br />
sumAll [] = 0<br />
<br />
This is a recursive function. It takes a list of 'a' in Num and returns an 'a'. However, there seem to be two definitions for sumAll. And there are. This is how pattern matching works. The two definitions have different specifications for their parameters, and each time sumAll is called, whichever pattern matches the parameters will be evaluated. Let's look at each definition. The second definition is the clearest. '[]' is the empty list, and sumAll of an empty list is defined here as zero. The middle line has something odd about it, though. '(x:xs)' is listed as a parameter, as if we were trying to stick something on the front of a list. In essence we are, because this pattern takes apart its input. There are a few patterns which do this, and this feature of Haskell makes lists very easy to use. To restate, when '(x:xs)' is written as a parameter in a function definition, it will only match lists which have an item stuck on the front. In other words, it will match lists with at least one member. The choice of variable names 'x' and 'xs' is completely arbitrary, but since 'x' will be 'bound' to the first member of the list and 'xs' will be 'bound' to the remainder of the list, it is somewhat natural to write one 'x', and then the remaining 'xs' when describing the list.<br />
<br />
When the pattern 'sumAll (x:xs)' matches the input, that is, when 'sumAll' is called with a list that has at least one value, the first definition will be evaluated. This will return the result of adding said first value to the result of calling sumAll on the rest of the list. Patterns are checked top-to-bottom, so when 'sumAll (x:xs)' fails to match, 'sumAll []' is checked. Since the only pattern that could fail to match 'sumAll (x:xs)' is an empty list, 'sumAll []' will definitely match, and it returns zero. This is the end condition for the recursion.<br />
<br />
This sort of function is very common in Haskell. Pattern matching lets us avoid complicated 'switch' statements or 'if' blocks in favor of simply writing separate definitions for distinct inputs. This allows code to be clear and concise. Patterns can also be more specific. The fib example can be rewritten as follows:<br />
<br />
fibPat :: (Num a, Num b) => a -> b<br />
fibPat n = fibGenPat 0 1 n<br />
<br />
fibGenPat :: (Num a, Num b) => b -> b -> a -> b<br />
fibGenPat a _ 0 = a<br />
fibGenPat a b n = fibGenPat b (a + b) (n - 1)<br />
<br />
Again, the names are changed to avoid conflicts in the examples, adding 'Pat'. Here a literal ('0') is used to match a pattern, and that is fine, too. Also note the underscore ('_') in the first definition. The underscore matches anything, just like a variable name, but does not get 'bound' to its parameter. This can make code clearer when a parameter is not used. In this case, we do not care about the second parameter, since we are only matching against the third and returning the first.<br />
<br />
<br />
===Part II: After Patterns, Guards===<br />
<br />
Sometimes functions need more complicated work to choose between definitions. This can be done with guards, shown here:<br />
<br />
showTime :: Int -&gt; Int -&gt; String<br />
showTime hours minutes<br />
| hours == 0 = "12" ++ ":" ++ showMin ++ " am"<br />
| hours &lt;= 11 = (show hours) ++ ":" ++ showMin ++ " am"<br />
| hours == 12 = (show hours) ++ ":" ++ showMin ++ " pm"<br />
| otherwise = (show (hours - 12)) ++ ":" ++ showMin ++ " pm"<br />
where<br />
showMin<br />
| minutes &lt; 10 = "0" ++ show minutes<br />
| otherwise = show minutes<br />
<br />
Ignore the lines after the 'where' for the moment. 'showTime' has only one definition clause, but it is broken up into three guards. Each guard has a boolean expression, and they are checked in order. The first which is found to evaluate to True will have its corresponding expression evaluated and returned. The function will be equal to that expression for the case that that guard is true. 'otherwise' is equal to True, and will therefore always be accepted if it is reached. 'otherwise' is a convenience, not a necessity. '++' is the list concatenation operator. It is used here for the following reason:<br />
<br />
String :: [Char]<br />
<br />
So all of that makes sense except for the 'where' stuff. Here I threw in something extra, and used a 'where' clause to define a local function, in this case a variable called 'showMin'. 'showMin' is a variable in the traditional sense, but it is also a function here in Haskell, so instead of an 'if' statement or 'case' statement, I used guards again to describe its two definitions.<br />
<br />
In all, this function takes an hour (hopefully from 0 to 23) and minutes (hopefully from 0 to 59) and prints the time from them. 'showMin' is a local variable/function, defined in the where clause. Guards are used both to define 'showTime' and 'showMin'.<br />
<br />
It is important to note that the variables defined in 'where' clauses and their cousins, 'let' clauses, are only in scope for the pattern in which they exist. So a function defined with multiple patterns can't use a 'where' clause to define a local variable across all of them.<br />
<br />
<br />
===Part III: 'If'===<br />
<br />
I mentioned 'if' statements just above, and Haskell has them, but they are always if-then-else. Haskell doesn't have much use for a function that doesn't return some kind of value, so 'if-then' doesn't work. That said, here's a simple example:<br />
<br />
showMsg :: Int -&gt; String<br />
showMsg n = if n &lt; 70 then "failing" else "passing"<br />
<br />
Not much to it. Since 'showMsg' has a return type of String, the values in both the 'then' clause and the 'else' clause have to also be of that type. 'if' does not need to be the entire definition of a function. For instance:<br />
<br />
showLen :: [a] -&gt; String<br />
showLen lst = (show (theLen)) ++ (if theLen == 1 then " item" else " items")<br />
where<br />
theLen = length lst<br />
<br />
<br />
===Part IV: Indention Syntax===<br />
<br />
You may have noticed that I use indention to indicate lines that are part of a block of source code. This is not simply good style, but it is also part of Haskell's syntax. Indentation denotes structure. Specifically, changing the indentation from one line to the next indicates that a block of code has begun or ended. Also, Haskell will not let you place the definitions for two functions one line after another. Instead it demands a blank line to indicate that the definition of a function has truly finished. This all enforces good style, and it greatly reduces the amount of junk syntax in the language, such as '{', '}', and ';'.<br />
<br />
<br />
===Part V: And Lambda Functions===<br />
<br />
Given a programmer's ability to define functions locally in Haskell, you might ask, &quot;Is there an even more brief way of defining functions?&quot; Unlike this tutorial, Haskell does let you finish quickly:<br />
<br />
(\x y -> x * 4 + y) :: Num a => a -> a -> a<br />
<br />
What is this you ask? It all starts with the '(\' right at the beginning. '\', you see, looks a little like the greek letter lambda, which happens to be the symbol used for Haskell itself:<br />
<br />
[http://www.haskell.org/ http://www.haskell.org/]<br />
<br />
'Lambda calculus' is a branch of mathematics that deals with functions created on the fly. There's a lot more to it, such as its place in computation theory, etc. You can find out more about it other places. The point is that when you write '(\', you have started a 'lambda expression', which generally look a lot like the one above. It has '(\', then some variable names (usually short ones), a '-&gt;' arrow, and an expression which uses those variables. And of course a ')'. I'm sure you can figure out what this does. It defines a function and uses it right where it is defined. For example:<br />
<br />
Prelude&gt; map (\x -&gt; "the " ++ show x) [1, 2, 3, 4, 5]<br />
["the 1","the 2","the 3","the 4","the 5"]<br />
Prelude&gt;<br />
<br />
I mention lambda functions because they come in handy, but also because they are used often in the more complicated examples. Of course, lambda functions cannot be recursive, since they would need a name in order to refer to themselves. So they are good for those cases where a function is needed only once, usually to define another function.<br />
<br />
<br />
===Part VI: Polymorphic Types and Type Constructors===<br />
<br />
The simplest Haskell program is the following:<br />
<br />
main = return ()<br />
<br />
The variable 'main' is a reserved word, and whatever its value is, the program executes. Here is the obligatory &quot;Hello World&quot; program:<br />
<br />
main = putStrLn "Hello World"<br />
<br />
And the type of 'main':<br />
<br />
main :: IO ()<br />
<br />
This is another way of saying &quot;main is of type something or other&quot;. Well, that's how it looks anyway. What we have here are examples of two strange things at once. That happens a lot when you're learning Haskell, and that's why I'm writing such a long tutorial in the first place. '()' is a type. The only value of type '()' is written '()'. Another word for this type and its singular value is 'null'. So this type can be read &quot;main is of type IO null&quot;. But why is it read that way? What does it mean to put one type after another? IO is not a type. The word 'IO' is only part of a type. 'IO a' is a type. 'IO' is a type constructor which takes a type as a parameter. Deep breath.<br />
<br />
This is not the same thing as a class. When we were talking about classes, I said that functions were polymorphic, meaning that they could operate on values of any type provided that the proper functions were defined for it. You can create a type and make it a member of Num, as long as it has '+', '-', and '*' defined for it, as well as having equality defined. If you do that correctly, any function which has 'Num a =&gt;' at the beginning of its type will accept your new type and everything will work fine. But 'IO' isn't a class, or a polymorphic function. This is something stranger. It is a polymorphic type.<br />
<br />
Did that make sense? A type that takes another type as a parameter? Let's look at an example from the standard libraries:<br />
<br />
data Maybe a = Nothing | Just a<br />
<br />
This type can be found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html]<br />
<br />
This is a 'data' type definition. The values on the right are separated by '|', the pipe symbol, which can be read here as &quot;or&quot;. This type says, &quot;a value of type 'Maybe a' can be 'Nothing', or can be 'Just a'&quot;, that is 'Just' followed by a value of type 'a'. Here's an example using Maybe in pattern matching:<br />
<br />
showPet :: Maybe (String, Int, String) -> String<br />
showPet Nothing = "none"<br />
showPet (Just (name, age, species)) = "a " ++ species ++ " named " ++ name ++ ", aged " ++ (show age)<br />
<br />
'showPet' has two patterns. The first matches a value of 'Nothing', the first 'data constructor' for Maybe. There are no variables after 'Nothing', just as there are no types listed after 'Nothing' and before the '|' in the type definition for 'Maybe a'. The second matches a value of 'Just', the second 'data constructor' for Maybe. 'Just' does have a tuple after it, just like in the type definition, and parentheses are used to group these two things in the pattern. The words 'Just' and 'Nothing' are arbitrarily chosen, although good choices. It is important that the first letter is capitalized. As you may have noticed, throughout Haskell, variables have lowercase first letters and types have uppercase first letters. This is a part of Haskell's syntax. Data constructors are not variables, and so the convention is extended to require their first letters to also be capitalized.<br />
<br />
<br />
===Part VII: The IO Monad===<br />
<br />
So let's get back to 'main' and its type, 'IO ()'. IO is a polymorphic type. But what is it? Unfortunately, I cannot show you its definition. 'IO a' is a part of the Haskell standard, and most of its implementation is 'under the hood'. Its implementation is also very large, and involves a lot of low-level code. 'IO' is a member of the class Monad, which means (very briefly) that it lets you write sequential-looking code using the 'do' notation which I'll show in minute. 'IO' is also short for Input/Output of course, and that means that the 'under the hood' functions of IO let you read and write the world state. So 'IO' is how Haskell interacts with the real world. Again:<br />
<br />
main :: IO ()<br />
<br />
Monads are odd things, and a function of type 'IO a' will perform an 'IO' operation and return a value of type 'a'. In this case, main will return a value of type '()', namely '()', or 'null'. So main is always &quot;an IO operation that returns null&quot;. Here is short main function, with types. Note that it is never necessary to specify the type of main.<br />
<br />
someFunc :: Int -&gt; Int -&gt; [Int]<br />
someFunc .........<br />
<br />
main = do<br />
putStr "prompt 1"<br />
a &lt;- getLine<br />
putStr "prompt 2"<br />
b &lt;- getLine<br />
putStrLn (show (someFunc (read a) (read b)))<br />
<br />
Here's what's going on: The IO Monad binds blah blah blah that's all in the other tutorials and yet you're reading this. Let's try again.<br />
<br />
Here's what's going on: All of that 'variable equal at all times' stuff I mentioned in previous sections doesn't work with I/O. After all, you have to call 'getLine' several times, and it doesn't always return the same value. You can't say that the function 'getLine' is &quot;equal&quot; to anything, since its value may be different every time it is referenced. This is in contrast to a value, like '4', which will always be the number 4. So IO is hard to do if you want a language that has true &quot;equality&quot; when you write an assignment. '''This has actually been the biggest stumbling block for functional language design since the idea of functional languages arose. Haskell has a solution.'''<br />
<br />
Most functional languages break their 'functional model' to handle IO, but of course Haskell does something weirder. There's an obscure branch of mathematics, namely monads, that concerns state transformation functions. The authors of Haskell used it to let you write mathematical functions that denote changes in the world's state without breaking that nice equality stuff. <nowiki>[How's that for simple? See how I made it all make sense by appealing to a higher authority? Haskell works by magic! -Eric]</nowiki><br />
<br />
Briefly, the IO monad takes the state of the world, alters it with some function, and passes it forward to be the input for another IO function. In the example, the functions 'putStr', 'getLine', and 'putStrLn' are members of IO. 'Binding' them to 'main' by using the 'do' notation means that when 'main' is evaluated, they will be evaluated in order, just like you'd expect. Thus the main function of the program above will put a prompt on a screen and read in a string, and then do it again, then print something. The '(read x)' function takes a string and returns a number of whatever type is needed, assuming the string parses. The 'show' function will take the result from 'someFunc' and turn it into a string so that putStrLn can display it. I will return to this code and make it useful later.<br />
<br />
The description of IO may sound like 'imperative' behavior, and it is, with a twist. Input and output need to happen in a certain sequence in a program, but a mathematical function's parts can be determined in any order as long as it eventually finishes. Sequence doesn't matter for the evaluation of a mathematical definition, and most Haskell code is written in that manner. So what about input and output? Can they be mathematically described? As it turns out, they can. Monad theory means that a function can be &quot;equal&quot; to the act of transforming a state. The mathematical framework for monads captures the idea of sequenced actions, and that let Haskell's creators give 'IO a' a type that could be used just like any other type. When a sequence of monad functions are evaluated, for instance when 'main' is evaluated, the monad functions are applied in sequence to the initial state. Before that evaluation, Haskell gets to treat functions of type 'IO a' just like anything else, i.e. as expressions waiting to be evaluated. That means that the 'IO a' type doesn't have to be a special, builtin part of Haskell, even though input and output have to be part of the standard libraries and implemented with system calls. It does mean that doing IO in Haskell means using a polymorphic type as well as a mathematical theory that is rather obtuse. That's why IO is so far down in this tutorial.<br />
<br />
All Haskell functions carry around this mathematical framework (&quot;equality&quot;) and unless otherwise noted, they are lazy. This means that the only thing that forces evaluation is binding an 'IO monad' function to 'main'. '''Nothing is ever evaluated unless it is going to be the return value of an evaluated 'monad' function, or unless it is needed to compute such a return value.''' That the 'IO monad' forces evaluation isn't really important, but it will explain some odd behavior if you start doing &quot;out there&quot; coding in Haskell. There are eager, or 'strict' functions in Haskell which, when evaluated, will first fully evaluate their parameters. These are usually marked in the documentation.<br />
<br />
It is possible to use the IO monad, illustrated above, to write imperative-style programs in Haskell. That is a direct result of the behavior of the IO monad. Doing so would be inappropriate, because Haskell has much more power than that. I say that because I have not seen any other tutorial do so, and I think it is important.<br />
<br />
If you write programs that call outside libraries, you'll deal with the IO monad a lot. Everything that deals with the rest of the computer is part of the IO monad, such as driver calls, network libraries, file access, threading, and system calls. There are other monads in Haskell's libraries, and you can also write your own. Writing your own monad for a major project will probably be the other hard thing you need to do to fully understand Haskell, after understanding 'foldr' and variants. It's pretty hard, but not because it's complicated. Writing your own monad is hard because there's so little to do that you'll have to work to understand why that little bit of code is all you need. This tutorial ends with an extended example that demonstrates how to write a monad from scratch, but it may not be necessary for a general Haskell programmer to learn that.<br />
<br />
<br />
===Part VIII: Dissecting the IO Example===<br />
<br />
Let's return to basic IO monad usage. Here's the example main program again:<br />
<br />
someFunc :: Int -&gt; Int -&gt; [Int]<br />
someFunc .........<br />
<br />
main = do<br />
putStr "prompt 1"<br />
a &lt;- getLine<br />
putStr "prompt 2"<br />
b &lt;- getLine<br />
putStrLn (show (someFunc (read a) (read b)))<br />
<br />
'''This is a general framework for learning Haskell.''' Aside from altering the number of parameters to 'someFunc' (perhaps zero), this is all you will really need for a main function until you feel comfortable with Haskell. It is good enough for most simple tasks, and you can use it to test out ideas in GHC by replacing the definition of 'someFunc' with whatever function you're trying to write. You won't need it for working in Hugs or GHCi, but you will if you compile with GHC. In Hugs and GHCi, you only need to make a source code file that includes someFunc's definition.<br />
<br />
What I said earlier about the indentation technique removing extraneous syntax isn't quite true. '{', '}', and ';' do exist in Haskell. They are an alternative to the the whitespace-defining notation used here, and are sometimes but rarely preferable. The whitespace method is very simple, and the example shows most of its syntax. Blocks begin on tabbed or spaced lines and further indention is used for separate blocks. Using 'do' signals to the compiler to expect indentation based on whitespace unless you then use '{', '}', and ';'.<br />
<br />
The '(read x)' items use the 'read' function found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Aread The Prelude: the 'read' function]<br />
<br />
'someFunc' is whatever you want to test. Since its return value is a parameter to 'show', 'someFunc' can be defined with a variety of return types, such as 'Int', '[Int]', 'String', or even '(String, [Int])'. The type of 'show' is given here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3AShow The Prelude: the 'show' function]<br />
<br />
'show' is a class method defined for members of the class 'Show'. This is just like how '+' and '*' are class methods defined for members of 'Num'. You can see those here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3ANum The Prelude, section: the Num class]<br />
<br />
The types of the IO functions, specifically 'putStr', 'getLine', and 'putStrLn', are given here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#g:20 System.IO, section: Special cases for standard input and output]<br />
<br />
and also here, in the Prelude, which is why they are in scope normally:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:25 The Prelude, section: Simple I/O operations]<br />
<br />
As you can see from the documentation, when putStrLn is applied to a String, you get a value of type 'IO ()'. The 'null' means that no useful information is returned by the function. It altered the state of the IO monad by putting something on the screen, and no value comes back from it.<br />
<br />
The '&lt;-' arrow is used to bind the result of an IO operation to a variable. 'getLine' has a type of 'IO String'. The 'do' notation says that a monad function like 'getLine' can be prefaced by a variable name and the left arrow. That variable name comes into scope at that point in the function and when the monad function is evaluated, and its return value will be assigned to the variable. If a function is not prefaced by a left arrow and a variable, then its return value is ignored, although whatever that function did to the state carried by the monad still happens. For instance, if you do not bind the return value of 'getLine' to a variable, you don't store the line the user typed in, but it is still read in and buffers are messed with, etc., meaning that another getLine won't return it.<br />
<br />
There is one exception to this 'ignoring' of return values not bound to variables. It is no accident that the last line in the sequence has the same return type as main. When using monads to compose sequences of operations, the last line in a function must have the same IO type as the function itself. When this is not natural, use 'return' with an appropriate value:<br />
<br />
getName1 :: IO String<br />
getName1 = do<br />
putStr "Please enter your name: "<br />
name <- getLine<br />
putStrLn "Thank you. Please wait."<br />
return name<br />
<br />
'putStrLn' has a type String -&gt; IO (), but IO () doesn't match the type of 'getName', which is IO String. 'return name' is used to end the function with a function of the proper type, and to return the data we wanted to return. Without the reply message, this function can be written much more succintly:<br />
<br />
getName2 :: IO String<br />
getName2 = do<br />
putStr "Please enter your name: "<br />
getLine<br />
<br />
As you can see, calling an IO function which returns a value is the same as binding that value to a variable and then returning that value.<br />
<br />
This whole monad issue looks imperative, and in some ways, it is. Once you call 'someFunc', you get away from all that, and Haskell's laziness and equality become the norm. Is all of this necessary? Is it a good idea to have imperative-looking code calling lazy, functional code? In my opinion, it can be. You get to specify the order of execution for those operations that require it (such as IO), and you get powerful functional tools the rest of the time. You also get a hurt head. So take a break. I need one from writing all of this. The next section will be on advanced type declarations.<br />
<br />
<br />
==Section IV: Haskell and You==<br />
<br />
===Part I: Where Are the 'For' Loops?===<br />
<br />
As you may have noticed, the aren't any 'for' loops in Haskell. You could write them using IO monad functions, but I said that wasn't the right thing to do. So where are they? If you've already figured Haskell out, you can skip this section, but for those you like me that needed a lot of assistance, read on.<br />
<br />
'for' loops are unnecessary. Not just in Haskell, but in general. The only reason that you have ever used 'for' loops is that you had to 'do' something to a chunk of memory to store the right value in the right spot. Haskell frees you from this, and when you got lost and wonder where your 'for' loops are, check here:<br />
<br />
bar :: Int -> Int<br />
bar = ...<br />
<br />
foo :: [Int] -> [Int]<br />
foo (x:xs) = bar x : foo xs<br />
foo [] = []<br />
<br />
That looks a little too easy, and is actually equivalent to 'foo = map bar'. Here's a less contrived example. What if you were implementing a physics simulation, gravity for example, and you needed to calculate a new position of each object based on the other objects' positions? The following function calculates part of the process, which is finding, for each object, the sum of its mass times another object's mass divided by distance, over all other objects. In C, this would be accomplished by a pair of nested for loops, the outer one reading the mass and position from an array of objects, and the inner one computing mass1 times mass2 over the distance and summing it. Here are the types for that operation in Haskell:<br />
<br />
--types for variables<br />
type Mass = Double --only a type rename, but useful for clarifying parameters<br />
type Pos = (Double, Double, Double) --x, y, z<br />
type Obj = (Mass, Pos) --interchangeable with (Double, (Double, Double, Double))<br />
<br />
--list of functions needed<br />
{-<br />
Takes a list of objects.<br />
Returns a list of (sum of mass times other object mass over distance for all objects)<br />
Order is preserved.<br />
-}<br />
<br />
--overall function type<br />
calcMassesOverDists :: [Obj] -> [Double]<br />
<br />
That's definitely the setup. I defined some types for keeping track of the variables, listed the mathematical operations needed, and defined a type for the overall function. In the above code, '--' indicated that the rest of the line is a comment. '{-' and '-}' open and close block comments.<br />
<br />
The reason that I separate this from the code is that it is unlikely to change, while code is likely to be altered, optimized, debugged, etc. With some useful comments, here's one way to write the code:<br />
<br />
--Here we pass the objects in as two parameters to the helper function so we can iterate twice.<br />
--This does not copy the list of objects.<br />
calcMassesOverDists :: [Obj] -&gt; [Double]<br />
calcMassesOverDists objs = calcHelper objs objs<br />
<br />
--This is a function that computes a distance between two Pos values, used in calcMMoD.<br />
distXYZ :: Pos -&gt; Pos -&gt; Double<br />
distXYZ (x1, y1, z1) (x2, y2, z2) = sqrt (xd * xd + yd * yd + zd * zd)<br />
where<br />
(xd, yd, zd) = (x1 - x2, y1 - y2, z1 - z2) --three assignments at once using a tuple<br />
<br />
--This iterates over the list of objects and calculates the sum for each.<br />
--It uses pattern matching to recurse and terminate.<br />
calcHelper :: [Obj] -&gt; [Obj] -&gt; [Double]<br />
calcHelper (obj:objs) objList = (sum (calcMMoD obj objList)) : calcHelper objs objList<br />
calcHelper [] _ = []<br />
<br />
--This calculates the list of mass times mass over distance for a single object.<br />
--It uses pattern matching to recurse and terminate and a where clause to keep the code clear.<br />
calcMMoD :: Obj -&gt; [Obj] -&gt; [Double]<br />
calcMMoD obj@(m1, pos1) ((m2, pos2):rest) = safeValue : calcMMoD obj rest<br />
where<br />
dist = distXYZ pos1 pos2<br />
safeValue = if pos1 == pos2 then 0 else m1 * m2 / dist<br />
calcMMoD _ [] = []<br />
<br />
I threw something extra in there, specifically 'obj@' in front of '(m1, pos1)'. The '@' is read 'as', and it means that 'obj' will refer to the whole value of type 'Obj', while '(m1, pos1)' will pattern match against the values in 'obj'. It's handy, because otherwise I would have to write '(m1, pos1)' again when I called 'calcMMoD' recursively, and I might make a typo when I did. Also, it's clearer. Note also that I did not have to completely 'take apart' obj. I left the value of type 'Pos' bound to 'pos1'. And note that I put all the sub-computations for 'distXYZ' into one line to save space. I defined the tuple '(x1 - x2, y1 - y2, z1 - z2)', and then bound it to the pattern of '(xd, yd, zd)', thus defining 'xd', 'yd', and 'zd' how I needed to. Finally note that dist is not evaluated in a call to calcMMoD if pos1 == pos2, and neither is m1 * m2 / dist, which avoids the division by zero.<br />
<br />
I can compare equality between pos1 and pos2 because a tuple of types which are all in the class 'Eq' is also in the class 'Eq'. The definitions allowing that are here, although you have to scroll down several pages:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3AEq The Prelude, section: the Eq class]<br />
<br />
What you're looking for is a line like this:<br />
<br />
(Eq a, Eq b) => Eq (a, b)<br />
<br />
When listed in the 'Instances' section of the Eq class, that means that somewhere in the source code for the Prelude, there is an instance of Eq defined for '(a, b)' with the condition that both a and b are also members of Eq. The definition of that instance is fairly straightforward; the point is that it is there. Because it is present, any tuples of size 2 (and also those of many larger sizes) whose items are all members of the Eq class, and those tuples can be compared using '==' and '/=' without any further work on your part.<br />
<br />
'sqrt' is a class function, and is defined (separately) for all types in the class 'Floating', which of course includes 'Double'. The type of 'sqrt' can be found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3AFloating The Prelude, section: the Floating class]<br />
<br />
'sum' is a polymorphic function, and is defined (one time) for all types in the class 'Num', which also of course includes 'Double'. The type of 'sum' can be found here:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:13 The Prelude, section: Special Folds]<br />
<br />
I could have had calcMMoD return the sum, but code will compile to a more efficient result if the tasks are broken up, since 'sum' in the Prelude is based on a tail-recursive and (I believe) highly optimized function. The definition of 'sum' is in the Prelude, and more about 'tail recursion' can hopefully be found here:<br />
<br />
[http://en.wikipedia.org/wiki/Tail_recursion http://en.wikipedia.org/wiki/Tail_recursion]<br />
<br />
So where are the 'for' loops? Each recursive function iterates over a list, and the two together act as a nested pair of 'for' loops. This code is good, but there is a quicker way to write 'calcMassesOverDists' and 'calcMMoD', with the same types, and using a much simpler helper function for 'calcMMod'. Here is a cleaner implementation:<br />
<br />
--Here we use 'map' instead of writing the recursion out.<br />
calcMassesOverDists :: [Obj] -&gt; [Double]<br />
calcMassesOverDists objList = map (\obj -&gt; sum (calcMMoD obj objList)) objList<br />
<br />
--Again, we use 'map' instead of writing the recursion out.<br />
calcMMoD :: Obj -&gt; [Obj] -&gt; [Double]<br />
calcMMoD obj objList = map (mMoDHelper obj) objList<br />
<br />
--Here we don't bother spacing out the code since we're not forming a list any more.<br />
--Note that this function no longer operates or returns a list.<br />
mMoDHelper :: Obj -&gt; Obj -&gt; Double<br />
mMoDHelper (m1, pos1) (m2, pos2) = if pos1 == pos2 then 0 else m1 * m2 / distXYZ pos1 pos2<br />
<br />
--This is unchanged.<br />
distXYZ :: Pos -&gt; Pos -&gt; Double<br />
distXYZ (x1, y1, z1) (x2, y2, z2) = sqrt (xd * xd + yd * yd + zd * zd)<br />
where<br />
(xd, yd, zd) = (x1 - x2, y1 - y2, z1 - z2)<br />
<br />
I could have also avoided writing 'mMoDHelper' by using a lambda function:<br />
<br />
--Same as above.<br />
calcMassesOverDists :: [Obj] -&gt; [Double]<br />
calcMassesOverDists objList = map (\obj -&gt; sum (calcMMoD obj objList)) objList<br />
<br />
--The code which avoids division by zero is now included here.<br />
calcMMoD :: Obj -&gt; [Obj] -&gt; [Double]<br />
calcMMoD (m1, pos1) objList = map (\(m2, pos2) -&gt;<br />
if pos1 == pos2 then 0 else m1 * m2 / distXYZ pos1 pos2) objList<br />
<br />
--This is unchanged.<br />
distXYZ :: Pos -&gt; Pos -&gt; Double<br />
distXYZ (x1, y1, z1) (x2, y2, z2) = sqrt (xd * xd + yd * yd + zd * zd)<br />
where<br />
(xd, yd, zd) = (x1 - x2, y1 - y2, z1 - z2)<br />
<br />
Or I could have avoided writing calcMMoD, but at that point it gets ridiculous:<br />
<br />
--Now we have nested lambda functions which avoid a function call.<br />
--Not really necessary, since no clarity is gained.<br />
calcMassesOverDists :: [Obj] -&gt; [Double]<br />
calcMassesOverDists objList = map<br />
(\obj1@(m1, pos1) -&gt; sum (map (\(m2, pos2) -&gt;<br />
if pos1 == pos2 then 0 else m1 * m2 / distXYZ pos1 pos2) objList) )<br />
objList<br />
<br />
--This is unchanged.<br />
distXYZ :: Pos -&gt; Pos -&gt; Double<br />
distXYZ (x1, y1, z1) (x2, y2, z2) = sqrt (xd * xd + yd * yd + zd * zd)<br />
where<br />
(xd, yd, zd) = (x1 - x2, y1 - y2, z1 - z2)<br />
<br />
In any case, the division by zero will not be evaluated if pos1 == pos2. In the first example, note that mMoDHelper starts with a lowercase letter as all functions and variables do. Also note that none of these take much code to write. Haskell is like that. mMoDHelper is partially applied in this example. It is given only one of its two parameters where it is written in calcMMoD. The type of 'mMoDHelper obj' in that expression is:<br />
<br />
mMoDHelper obj :: Obj -> Double<br />
<br />
This in turn is suitable as a parameter to 'map', as it only takes one parameter, rather than two.<br />
<br />
Not every instance of a for loop should be turned into a 'map'. In this case, there is the Prelude function 'sum', which will take the list generated by the 'map' in calcMMoD and return the sum of its values. There is not always a pre-built function for your purposes. List functions are part of Haskell's core tools, and there are more advanced functions to use when you need them, such as 'foldr' and its variants.<br />
<br />
Learning how to use 'foldr' and 'foldl' is a rite of passage for Haskell programmers. You will learn in time, by studying their definitions (in the Prelude) and definitions of other functions defined in terms of 'foldr' and 'foldl', such as 'concat', 'or', and 'sum'. For loops were just the beginning. When you get away from sequential behavior, real power comes out. Also, keep in mind that since foldr and map are used everywhere, GHC has heavily optimized them, and functions like them, so it's a good idea to use them.<br />
<br />
<br />
===Part II: Remember Lazy Evaluation? It's Still There===<br />
<br />
This section fleshes out the flexibility of the Haskell type system in a way that I haven't seen described for newcomers before. Hopefully, your are at least familiar with the concept of a 'Tree', that is, a data structure which has nodes that contain values and may also point to further nodes in the structure. 'Binary Trees' are one of the common forms, i.e. trees where each node has at most two children. For those of you for whom this is new, note this isn't a general graph. Trees aren't supposed to loop back on themselves; they just branch.<br />
<br />
data Tree a = Null | Node a (Tree a) (Tree a)<br />
<br />
This is a relatively complicated type. It is a 'data' type, defined with the reserved word 'data', like 'Maybe a' was. It is also polymorphic like 'Maybe a'; you can tell because the type, 'Tree a', takes a type variable. It has two data constructors, 'Null' and 'Node'. 'Null' has no arguments and 'Node' has three. The way it is named indicates that it is a tree, and on inspection it is a binary tree, having two children in 'Node'. So how would this work? First, let's write a value of this type:<br />
<br />
t1 :: Tree Int<br />
t1 = Node 3 (Node 2 Null Null) (Node 5 (Node 4 Null Null) Null)<br />
<br />
If we were to graph this tree, not including Null branches, it would look like this:<br />
<br />
3<br />
/ \<br />
2 5<br />
/<br />
4<br />
<br />
The first node has both a 'left' child and a 'right' child, and the 'right' child of the first node also has a 'left' child. Let us review 'constructors'. In this example 'Tree a' is a type, and 'Node' and 'Null' are 'data constructors' for that type. A data constructor, often simply called a constructor, acts like a function that groups together objects to form an object of a datatype. They only exist for types defined using 'data' or 'newtype'. Note that they are different from type constructors, such as IO and Maybe. Data constructors act like functions, and do not belong in type signatures. Type constructors act like functions on types, and '''only''' belong in type signatures. They do not live in the same namespace, so often a 'data' type will have a data constructor of the same name out of convenience.<br />
<br />
Constructors are also used to 'deconstruct' objects of 'data' types, like so:<br />
<br />
inOrderList :: Tree a -> [a]<br />
inOrderList Null = []<br />
inOrderList (Node item left right) =<br />
inOrderList left ++ [item] ++ inOrderList right<br />
<br />
'inOrderList' uses pattern matching to determine which constructor its parameter uses. Further, it 'deconstructs' a value that uses the constructor 'Node' and binds its member values to the variables 'item', 'left', and 'right', which are of types 'a', 'Tree a', and 'Tree a', respectively. We know these types because Node's definition reads, &quot;Node a (Tree a) (Tree a)&quot;, and 'a' is not further specified in this example. For those of you unfamiliar with trees, 't1' above is a 'binary search tree', and evaluating 'inOrderList t' will result in the following:<br />
<br />
*Main&gt; inOrderList t1<br />
[2,3,4,5]<br />
*Main&gt;<br />
<br />
Those values are in ascending order, since that is the definition of a 'binary search tree'. Read up on them if you're not familiar with them already.<br />
<br />
There's another funny thing about the definition of 'Tree a'. It's recursive. It used 'Tree a' to define each child. You can do that in Haskell as well as C, but as usual, there's a twist, and again as usual it involves lazy evaluation. In C/C++, to use a type in its own definition, you must declare a pointer to an object of its type rather than including it directly. In Haskell, pointers aren't used like that, so the type is included directly, as in the tree example. So what about this definition:<br />
<br />
foo :: Int -> Tree Int<br />
foo n = Node n (foo (n - 1)) (foo (n + 1))<br />
<br />
t2 = foo 0<br />
<br />
What is the value of 't2'? And what is its type? The value of 't2' requires an infinite amount of space to store. The first few levels of the trees could be drawn like this:<br />
<br />
0<br />
/ \<br />
-1 1<br />
/ \ / \<br />
-2 0 0 2<br />
/ \ / \ / \ / \<br />
<br />
And so on. But the type of 't2' is simple, and should be clear from the type of 'foo':<br />
<br />
t2 :: Tree Int<br />
<br />
When you get an error message (not if ever, but '''when''' you get an error message) that says &quot;can't do such-and-such, unification would result in infinite type&quot;, it means that the type would require an infinite amount of space to store. Typically this happens with pattern matching on lists. In that case a careful check will show that something incorrect in the code would have resulted in nested lists infinitely deep, meaning a type that looks like this:<br />
<br />
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[....<br />
<br />
And so on. But back to 't2'. Its type is not infinite, even though its type is defined recursively and t2 has a value that, when evaluated, would require infinite space to store. Because its type is defined recursively, Haskell (and you) know that values of type 'Tree a' can contain other values of type 'Tree a'. The fact that each value of type Tree a which is 'in' t2 uses the constructor 'Node' is not stored in the type of t2, so the type of t2 is finite and Haskell can use it. Also, multiple values of type 'Tree Int' can exist, some infinite, some not, and they all have the same type. Okay?<br />
<br />
<br />
===Part III: The Point(s)===<br />
<br />
I wrote all this about types to drive two points home. First, Haskell uses lazy evaluation. For example, the following type is valid and Haskell will not complain about it:<br />
<br />
data Forever a = AThing a (Forever a)<br />
<br />
It is a polymorphic type, it has a single constructor 'AThing', and it is recursive. Values of this type will always be infinite if fully evaluated. That's okay, and you could use this in a program if you wanted to. Haskell would not attempt to fully evaluate an object of this type unless you told it to.<br />
<br />
The second point is that learning and using Haskell requires unlearning and rethinking the basic assumptions most coders have developed about programming. Unlike so many languages, Haskell is not 'a little different', and will not 'take a little time'. It is very different and you cannot simply pick it up, although I hope that this tutorial will help.<br />
<br />
If you play around with Haskell, do not merely write toy programs. Simple problems will not take advantage of Haskell's power. Its power shines most clearly when you use it to attack difficult tasks. Once Haskell's syntax is familiar to you, write programs that you would ordinarily think of as too complicated. For instance, implement graph-spanning algorithms and balanced-tree data types. At first, you'll probably trudge ahead using 'imperative thought processes'. As you work, you'll hopefully see that Haskell's tools let you dramatically simplify your code.<br />
<br />
'''A big tip is, &quot;Don't use arrays.&quot;''' Most of the time, you need to access members of a list one at a time, in order. If that is the case, you do not need an array, and it would take you a lot of work to set one up. Use a list. If you are truly storing data that needs random access, still don't use arrays. Use lists and '!!'. When you need speed, then use arrays. Use Arrays, and then switch to IOArrays. But only use them if you actually need speed. Your class projects absolutely will not need arrays unless you are writing a game, or working on something for at least three months. Then, you might need fast random-access data. Maybe. Use lists.<br />
<br />
The tutorial has been expanded to include section six after the commentary, with examples. Additionally, all examples from these sections are included in source files as well. Hopefully, these will show how Haskell implementations differ from imperative code. Check them out and compare them to your own Haskell programs. My style is not perfect, but I know some good techniques. As a general rule, shorter, more concise source code makes programming and debugging faster. If you find yourself writing extensive cases or repeated code, that's probably unnecessary in Haskell.<br />
<br />
<br />
==Section V: Final Commentary==<br />
<br />
===Part I: Why is 'Referential Transparency' Worth Anything?===<br />
<br />
Functional languages have often been accused of generating slow code. This is not the case with Haskell, except for the Array type. Switch to IOArrays if you need speed. Anyway.<br />
<br />
Referential transparency gives Haskell programs two big boosts: better execution speed and memory use, and shorter, clearer code.<br />
<br />
First, here are some reasons why Haskell provides better speed and memory use. No code runs faster than code evaluated during compilation, except code optimized away during compilation. The easiest way to evaluate during compilation is to find where a value is assigned to a variable, find where that variable is next read, and hardcode the value in that place. This avoids a memory write, possibly a read, and also potentially some memory allocation.<br />
<br />
In both C and Haskell (for example), functions inherit the namespace of their scope. In C, this means that any variable in scope can be accessed at any time. For programming, this can be a good thing, or at least a time-saving feature. However, for compiling, this is a Bad Thing. Any of those accesses could be a write. Worse, you could have assigned a pointer the value of the memory space of a local variable, or be running a multi-threaded application. Or you could do pointer arithmetic and mess with any memory location at all. The behavior for handling this in C is compiler specific. C programmers are supposed to declare variables as volatile if they have this behavior. To correctly handle those cases, your compiler has to give up most of its hope of knowing how variables will be updated during execution.<br />
<br />
Since it is possible to write code that uses those techniques to update a variable when unexpected, the C compiler has to actually read a variable every time it is referenced unless it can '''prove''' that no update will touch that variable between two points in a program. Every function call potentially alters every variable in scope, within some limits, such as the assumption that non-volatile, non-global variables are unaffected. All data passed to a function in another module through a pointer not declared const must be re-read after the function call. That happens often in large projects.<br />
<br />
What about Haskell? Haskell is 'lazy and purely referentially transparent'. If you pass a value to a function, it will not be updated. That means that GHC can '''assume''' that. Specifically, there is never a need to copy a value when it is passed into a function, or ever re-read it. Also, a function which takes a list and returns part of that list hasn't copied anything. Since no update is possible, there is no harm in referencing the original. That's a big savings in memory, which translates into less memory reads and less page faults. Also, since the order of evaluation is unimportant to the programmer, the compiler can determine the fastest order and reshuffle the code and memory usage.<br />
<br />
Other things make Haskell code fast. First, Haskell's laziness adds an extra kick to the speed, since some code is never executed. Second, there are only a few pieces to Haskell: functions, if-then-else, polymorphic types, exceptions, the IO code, and a garbage collector. Most library list functions are built on foldr or a variant, if they do any real work at all. This is a very small number of pieces, and that makes Haskell easy to compile and optimize. Finally, GHC does cross-module optimization, even for library functions, something impossible in C.<br />
<br />
Contrast that to C/C++, with any number of libraries, most of them pre-compiled, and the only thing fast is memory manipulation. If you need memory manipulation, C is what you use. Python makes code-writing quick. LISP makes logical manipulation easy. Java makes code safely portable. Haskell is great (in my opinion) for the major target of industry: big projects with a lot of parts.<br />
<br />
Second, there is the source code itself. If you don't care about the order of execution, you can avoid using syntax to specify it. The best way to discover this is to try it yourself. If you're having trouble breaking your imperative habits, read other Haskell code until you can understand why it is so short. The examples in the next section have been included for that purpose. The source code of the Prelude itself is also a good place to look.<br />
<br />
<br />
===Part II: Feedback and Notes===<br />
<br />
If you liked this tutorial, it came in handy, it helped you understand Haskell, or you think I talk to much, write me at etherson@yahoo.com.<br />
<br />
Video games and other graphical applications written in Haskell can use HOpenGl and HOpenAL. To encourage this, Dave Morra has written a short tutorial on HOpenGL, although it is not currently online. Write me or look him up if you'd like to see that tutorial.<br />
<br />
The Gentle Introduction Haskell, useful as a reference:<br />
<br />
[http://www.haskell.org/tutorial/ http://www.haskell.org/tutorial/]<br />
<br />
The Tour of the Haskell Syntax, also a good reference:<br />
<br />
[http://www.cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html http://www.cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html]<br />
<br />
Finally, GHC's Hierarchical libraries, an excellent reference once you know the basics:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/index.html http://www.haskell.org/ghc/docs/latest/html/libraries/index.html]<br />
<br />
You should probably read the Gentle Introduction to Haskell and the Tour of the Haskell Syntax thoroughly. Hopefully a lot more should make sense now. There are a lot of little picky things in every programming language, and Haskell is no exception. Particularly, there are a few cases where strictness is an issue, and it's important to know how Haskell's syntax is interpeted. Good luck. Let me know if there's another tutorial I need to write, or about any bug in the big examples.<br />
<br />
<br />
===Part III: Ranting===<br />
<br />
We've covered a lot of the basics of using Haskell, and the next section has longer examples of Haskell code that go beyond toy programs. I'd like to take the time to talk about why I think Haskell is important, why I wrote this tutorial, and what learning Haskell was like for me. If you want to get to the examples immediately, go ahead and skip to the next section.<br />
<br />
During this tutorial, I refer to Haskell's 'power'. I am cribbing from an old equation about programming languages:<br />
<br />
flexibility * control of detail = a constant<br />
<br />
That statement should really be written as follows:<br />
<br />
flexibility * control of detail = '''''power'''''<br />
<br />
Haskell has both more flexibility '''and''' more control than most languages. Nothing that I know of beats C's control, but Haskell has everything C does unless you need to control specific bytes in memory. So I call Haskell powerful, rather than just 'good'.<br />
<br />
I wrote this tutorial because Haskell was very hard for me to learn, but now I love it. I haven't seen tutorials that addressed the difficulty that computer science students usually face with Haskell. I had to take two semesters of college that included Haskell before I really got a grip on it, and I only passed the first because one of my friends knew Haskell and helped me. I kept thinking that other people, maybe the haskell.org people, would write a tutorial aimed at C programmers, but it didn't happen. I understand why, now. As far as I can tell, Haskell is maintained and contributed to mostly by professors, and they have already learned LISP or other functional languages. Also, Haskell is not generally taught to whiny undergrads that throw a fit when faced with something this new and different. UT Austin is somewhat of an exception, and out of my classmates, I was the exception in actually liking it, let alone learning it.<br />
<br />
So a relatively small number of people have been in my position, and it seems like none of them have spoken up. Well, here it is. '''&quot;Haskell is hard!&quot; &quot;You can't write code the way I know how!&quot; &quot;My brain hurts!&quot; &quot;There aren't any good references!&quot;''' That's what I said when I was in college. There were good references, but they didn't cover the real problem: coders know C. We, as students just getting through our second or third advanced computer science course, expect sequential behavior for code. It isn't good enough for a book to say that Haskell does not execute commands in sequence. We can tell that. What we don't (and what I didn't) understand is why on Earth you would bother coding in a language that wasn't sort of like C, and how you would even think about it. We could read all these tutorials and a few books about the syntax of Haskell and how Haskell is lazy and has pure referential transparency, but none of that helps. We don't know how to put functions together. We don't know what ''will'' be evaluated, and we don't know how the pieces of Haskell syntax fit together. Haskell is so different from the industry standard (C/C++) that we can't look at complicated Haskell code and understand it. '''And if we don't, Haskell will always be an academic language.'''<br />
<br />
Of course, if a small horde of college kids start making little programs in Haskell, the language will survive, and maybe there will be a company that uses Haskell to make big games. I suppose there might be already. With OpenGL and OpenAL bindings, that's a guarantee. But only if students are using it, not just professors. When I started this tutorial, I wondered why the Haskell people didn't see this already. That's okay, they've been busy making a wonderful and extremely powerful language and libraries, and I thank them for it. Hopefully with good examples, applications, and games. Well, I'm done here. Thanks for reading all of this. Good luck with the big examples.<br />
<br />
<br />
==Section VI: Extended Examples==<br />
<br />
===Part I: Intro to Examples===<br />
<br />
This section covers the extended examples I have added to this tutorial. The entire set of examples can be downloaded as a .zip or .tar.bz2 archive.<br />
<br />
Again, here are the source files and text for all examples for this tutorial, including all those in the sections and the large examples at the end, zipped using bzip2: [[Media:HaskellForC_Examples.tar.bz2|bzip2 of sources, 28K]], and zipped as a zip: [[Media:HaskellForC_Examples.zip|zip of sources, 43K]].<br />
<br />
Lists of the relevant files are at the beginning of each part. As a reminder, for the examples in the sections, see the following:<br />
* ExampleSectionsCode.hs<br />
* ExampleSectionsTry.txt<br />
<br />
The examples use concise notation where the final appearance is clear, but this does not mean that it will be immediately clear to Haskell novices. Haskell encourages lengthy statements that can become difficult to comprehend, and I have attempted to break these up into smaller components that can be easily identfied and labeled.<br />
<br />
There are two extra pieces of syntax in the examples that I have not already covered in this tutorial. The first is the '$' operator. In some cases, I use the '$' operator to avoid deeply nested parentheses.<br />
<br />
sumListedv1, sumListedv2 :: Num a =&gt; [a] -&gt; [Int] -&gt; a<br />
sumListedv1 nums indices = sum (map (nums !!) indices)<br />
<br />
sumListedv2 nums indices = sum $ map (nums !!) indices<br />
<br />
'$' is a do-nothing operator; it's only point is to alter the precedence of the expressions on its left and its right. It takes two values as parameters and applies the first the the second. This is useless, mathematically, but it can let a programmer avoid parenthesizing lengthy expressions. I learned it from using HOpenGL, since many of the state altering functions take several lines of parameters.<br />
<br />
The second piece of syntax is the effect of backquotes, '`', which are below '~' on many keyboards. When placed around a function which accepts two parameters, backquotes make that function act like an operator.<br />
<br />
printIsMemberv1, printIsMemberv2 :: (Eq a, Show a) =&gt; [a] -&gt; a -&gt; IO ()<br />
printIsMemberv1 items item = if elem item items<br />
then putStrLn $ (show item) ++ " is a member of the list."<br />
else putStrLn $ (show item) ++ " is NOT a member of the list."<br />
<br />
printIsMemberv2 items item = if item `elem` items<br />
then putStrLn $ (show item) ++ " is a member of the list."<br />
else putStrLn $ (show item) ++ " is NOT a member of the list."<br />
<br />
'elem' takes two parameters, a single item and a list of the same kind and returns True if the single item is present in the list, otherwise False. In the second definition ('printIsMemberv2'), backquotes are use to use `elem` like an operator between its two parameters.<br />
<br />
I could have written my examples without these extra syntax niceties, but that would make them less like real code. If you've come this far, I believe that you can handle it.<br />
<br />
The examples aren't in order of importance. Skip around if you like, or skim the source code for style hints. Some of the examples involve complicated topics, but they are hopefully documented well enough that passing familiarity is sufficient.<br />
<br />
<br />
===Part II: Calculating Pi===<br />
<br />
'pi' is a builtin constant in Haskell, as it is in many languages. This example demonstrates some Haskell techniques by calculating pi in various ways. The easiest way to use this example is to load the source into GHCi and notice how long it takes each value 'pi1', 'pi2', and 'pi3' to evaluate the first time. The files:<br />
<br />
* ExamplePiCalc.hs<br />
<br />
In Haskell, 'pi' is defined in the 'Float' class here: <br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3AFloating The Prelude: the 'Float' class]<br />
<br />
Much of the math in the code was taken from this page:<br />
<br />
[http://en.wikipedia.org/wiki/Computing_%CF%80 Wikipedia's article "Computing Pi"]<br />
<br />
The values generated by the code differ slightly from the most accurate value possible. In two cases, the last digit is slightly off because the math used involves rounding the last digit. In the case of 'pi1', this is because greater accuracy is unattainable using that method without excessive computation.<br />
<br />
Once one of the constants has been evaluated, it will not be reevaluated if requested a second time. You can see this in GHCi by noting that 'pi1' takes several seconds or more to print the first time, but virtually no time after that. This is an example of lazy evaluation applied to constants.<br />
<br />
<br />
<br />
===Part III: MergeSort Variations===<br />
<br />
This example provides the functions 'mergeSort1', 'mergeSort2', and 'mergeSort3' as well as some simple test lists 'list1', 'list2', and 'list3'. The easiest way to use this example is to load the source into GHCi and try the different sort functions on various lists. Also try the function 'sort' in Data.List for comparison. The files:<br />
<br />
* ExampleMergeSort.hs<br />
<br />
This is not practical code, since the default 'sort' function is efficient for lists, but the variants illustrate a lot of the basics of Haskell. The default sort function can be reached in source code by putting "import Data.List" at the top and in GHCi and Hugs by using ":m Data.List". You have to load a module before a file in GHCi.<br />
<br />
For those unfamiliar with merge sort, the basic idea is that you sort two halves of a list separately, then do a simple merge operation the makes one sorted list from the two sorted halves. How do you sort the halves? By running merge sort on them, too. This splitting continues until you get to a manageable number of items, in this case down to zero or one. Then you merge back together.<br />
<br />
The versions of merge sort here do not vary that behavior. What is changed is some optimizations that try to avoid as much recalculation as possible. To split a list in half, you need its length. The first and simplest variant calculates that for every call, which arguably uses some redundant computation.<br />
<br />
The second variant tries to avoid this redundancy by passing around the length of the list and dividing it by 2 at ever call. This would result in some slightly lopsided merges, but no real loss of efficiency there. The gains would probably outweigh the loss.<br />
<br />
The third variant goes overboard and tries an optimization that is likely worse than the second variant. This is an example of a good idea which needs close examination. The third variant forms two halves by placing individual items alternately into two lists. This avoids recalculating the length with each call and avoids passing an integer and doing math with each call. However, about as much work is necessary to split the list in this manner as in the other methods, possibly more.<br />
<br />
<br />
===Part IV: Regular Expressions and Finite Automata: Overview===<br />
<br />
As I said before, Haskell's power only shines when it is used for larger projects. This makes it difficult to demonstrate Haskell's ability without writing code on topics that will be unfamiliar for some students. The smaller examples above and in the other sections of the tutorial are aimed at broad audiences, but such good examples are not necessarily available for more complex demonstrations.<br />
<br />
At the risk of alienating some readers, I have written a complex example covering regular expressions, finite automata, Haskell's module system, and writing your own monads. This is a big example and it covers a lot of ground. The files involved are:<br />
<br />
* ExREtoFAconvertDFA.hs<br />
* ExREtoFAconvertNFA.hs<br />
* ExREtoFAconvertRE.hs<br />
* ExREtoFAconvertREv1.hs<br />
* ExREtoFAconvertREv2.hs<br />
* ExREtoFAconvertREv2monad.hs<br />
* ExREtoFAconvertREv3.hs<br />
* ExREtoFAconvertREv3monad.hs<br />
* ExREtoFAexampleTests.txt<br />
* ExREtoFAexecution.hs<br />
* ExREtoFAmain.hs<br />
* ExREtoFAtypes.hs<br />
<br />
The code in this example takes a string and parses it according to a subset of the POSIX standard for regular expressions (REs), converting it into a structure suited for testing input. That structure is then converted to a non-deterministic finite automata (NFA) which will accept and reject equivalent inputs. Finally, that NFA is converted to a deterministic finite automata (DFA), although no great effort is made to minimize the number of states.<br />
<br />
If you don't know what either regular expressions or finite automata are, these are covered in detail in any undergraduate computer science education. If you are currently in school, you will get detailed instruction on them, probably soon. If not, these are topics you can learn at your leisure. I do not yet know if this example can be understood without a complete knowledge of the material. Please send me feedback about that.<br />
<br />
Whether or not you are familiar with these concepts, you can test the code with the examples in ExREtoFAexampleTests.txt. First you give a regular expression in POSIX notation as an input, then you repeatedly give strings to test against it. Use Ctrl-C to quit.<br />
<br />
The statements are printed as soon as each operation is done, so if a statement fails to appear, that operation went into an infinite loop. This occurs in some cases with the first implementation of running an NFA and is difficult to prevent in any implementation of running a regular expression directly. For that reason, and because DFAs can be executed more quickly, in practice REs (and NFAs) are converted to DFAs before use. My implementation uses a counter to test for deeply recursing execution so I can return a value indicating failure.<br />
<br />
<br />
===Part V: Regular Expressions and Finite Automata: Types===<br />
<br />
The 'types.hs' file for this example provides the types used in the rest of the files. In addition, the module provides functions that validate members of those types and functions which compute useful information from members of those types. This is the only module which does not include any other modules from the example. Files:<br />
<br />
* ExREtoFAtypes.hs<br />
<br />
The import statements in this file (and the rest) do not bring into scope everything from the standard modules they import. Instead, they only include the functions and types used in the code. Doing this helps track what functions are used where and prevents accidental clashes or similarities between names.<br />
<br />
The comments in this file also include a summary of the POSIX rules implemented.<br />
<br />
<br />
===Part VI: Regular Expressions and Finite Automata: String to RE, and Monads===<br />
<br />
The base file for this part of the example includes and re-exports three functions. There is one for each version implemented of the method to convert a string to the POSIX regular expression that it represents. Files:<br />
<br />
* ExREtoFAconvertRE.hs<br />
* ExREtoFAconvertREv1.hs<br />
* ExREtoFAconvertREv2.hs<br />
* ExREtoFAconvertREv2monad.hs<br />
* ExREtoFAconvertREv3.hs<br />
* ExREtoFAconvertREv3monad.hs<br />
<br />
The first method, implemented in 'convertREv1.hs', is a set of functions which work on the input string. They pass it around along with the pieces of regular expressions under construction. There is nothing wrong with this method, and in fact I only added the other methods as a final touch to the example. However, there is a lot of potential for mistakes when writing the code, because the precisely correct string must be passed forward, simulating using up the right amount of the input.<br />
<br />
This 'passing forward' nature made the conversion suitable for reimplementation as a Monad. Versions 2 and 3 of this conversion show how you can make your own monad. You create the type, not an intuitive task when you need to carry a state. You then write the instance declaration, the accessor functions, and functions which compose those accessors.<br />
<br />
Why use monads for this task? Note the types of the recursive functions:<br />
<br />
convertSREouter1 :: String -> MyRegExp -> Maybe (MyRegExp, String)<br />
convertSquareBlock1 :: String -> Maybe (MyRegExpItem, String)<br />
convertNumberBlock1 :: String -> Maybe (Int, Int, String)<br />
<br />
In each case, the inputs are returned, modified. This is a textbook case for creating a monad, or would be if any book existed with that hint. Using a monad lets us separate our changes to state, passed forward to the next function called, from our return values, passed upward to the calling function.<br />
<br />
Since a String is passed forward in every case, that will be the monad's state, its internal value. The rest of the data will be normal return values. The functions have almost exactly the same structure, but the code is clearer.<br />
<br />
The instance was very hard for me to write. There are two issues, the first being that the syntax for Instance declarations is tricky to find. The second is that, even armed with the type of (>>=), the functions are difficult to write. Let's analyze them. Here's what GHCi says about (>>=):<br />
<br />
Prelude> :t (>>=)<br />
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b<br />
<br />
At least we can tell that it has two parameters, one of type 'm a' and one of type '(a -> m b)'. The immediate question, if you can understand the types, is, &quot;Why is the monad type passed a type variable as if it is a type constructor?&quot; It seems like, even if you define a type that doesn't take a variable, if you define it as an instance of Monad, it has to take a type variable.<br />
<br />
The truth is that a monad must take a type variable. This variable type is used to pass back results.<br />
<br />
What is not mentioned anywhere is how to handle passing a state forward. A monad data type does not contain a state. If you use a state, your monad type must instead be a function which takes a state and then returns it. In this way, the function describes how to transform a state. For instance, the following code does not work:<br />
<br />
newtype REmaker2 a = RE2 (String, a)<br />
<br />
Where things fail is that you will find no way for the bind operation (&gt;&gt;=) to take the existing state as an input. This is not fixed by altering the bind method or the function to be bound, but only by altering the type of the monad itself so that a later instance takes the new state as a parameter. This is not intuitive for me and not something that I can do without the examples I listed.<br />
<br />
You also have to wrap up your type for a Monad in a 'newtype' declaration (or a 'data' declaration) so that it works in an Instance declaration. Haskell will not let you define an instance for a type other than those.<br />
<br />
When I was working with this example on monads, I used a lot of help from here:<br />
<br />
[http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm]<br />
<br />
The third version is very similar to the second, but show how some extra access functions can make code simpler. Both files make use of a separate file to store their types. The export list for those sub-modules specifically fails to export the constructor for the monad type. This forces the functions outside that sub-module to only modify and use the monad using the exported accessor and run functions. This is done to make the data type abstract and keep code clean.<br />
<br />
It is worth noting that even with the data type in a separate file, the code is longer when implemented using a Monad. The syntax of monads is slightly more verbose, and can create some awkwardness in smaller projects such as this. As a project scales in size, the gains increase when using monads in cases for which they are appropriate. Many of the gains come from lack of errors in carrying state forward, which is most of the point in the first place.<br />
<br />
<br />
===Part VII: Regular Expressions and Finite Automata: Conversion and Execution===<br />
<br />
The remaining conversion files for this example implement some standard algorithms for converting REs to NFAs and NFAs to DFAs. The code is complex and shows a lot of the power of Haskell. The majority of the source code is comments rather than code. In addition, the code was written as clearly as possible rather than focusing on brevity. Hopefully, this will help the reader follow along. Files:<br />
<br />
* ExREtoFAconvertDFA.hs<br />
* ExREtoFAconvertNFA.hs<br />
<br />
The execution file for this example uses multiple methods to test input strings against the resulting structure from each point in the conversion process. The key distinctions are that some methods track the set of reachable states simultaneously, accepting when any reachable state would accept, and other methods make a separate recursive call for all branches. The branching method is prone to infinite loops. The fact that REs and NFAs branch, while the end result, DFAs, do not branch, illustrates why this conversion is usually performed. Files:<br />
<br />
* ExREtoFAexecution.hs<br />
<br />
In the main program for this example, these execution methods are ordered and displayed. Extensive use is made of basic operations in the IO monad, and this file can serve as an example for that as well, particularly the need to flush buffers after writes which do not end in a newline. Files:<br />
<br />
* ExREtoFAmain.hs<br />
<br />
<br />
===Part VIII: Solving 2CNFs in Linear Time===<br />
<br />
The final example, currently, is an abbreviated demonstration of list comprehensions and the 'data' data type declaration. The program solves boolean equations in conjunctive normal form with two variables each, also called 2CNF. This is widely known as a special case of the NP-Hard CNF problem. The files:<br />
<br />
* Example2CNF.hs<br />
<br />
The source code for this example indicates several ways to expand on it.<br />
<br />
<br />
===Part IX: In Closing===<br />
<br />
There are some extremely complex graph algorithms that I would like to provide as examples. For now, I'm done here. Thanks for reading all of this.<br />
<br />
Eric Etheridge, etherson@yahoo.com</div>Heisenbughttps://wiki.haskell.org/index.php?title=Type_arithmetic&diff=57855Type arithmetic2014-04-11T14:01:28Z<p>Heisenbug: typo</p>
<hr />
<div>'''Type arithmetic''' (or type-level computation) are calculations on<br />
the type-level, often implemented in Haskell using functional<br />
dependencies to represent functions.<br />
<br />
A simple example of type-level computation are operations on [[Peano numbers]]:<br />
<br />
<haskell><br />
data Zero<br />
<br />
data Succ a<br />
<br />
class Add a b ab | a b -> ab, a ab -> b<br />
instance Add Zero b b<br />
instance (Add a b ab) => Add (Succ a) b (Succ ab)<br />
</haskell><br />
<br />
Many other representations of numbers are possible, including binary and<br />
balanced base tree. Type-level computation may also include type<br />
representations of boolean values, lists, trees and so on. It is closely<br />
connected to theorem proving, via<br />
[http://en.wikipedia.org/wiki/Curry-Howard the Curry-Howard isomorphism].<br />
<br />
A [http://okmij.org/ftp/Haskell/number-parameterized-types.html decimal representation] was put forward by [http://okmij.org/ftp/ Oleg Kiselyov] in [http://www.haskell.org/haskellwiki/The_Monad.Reader/Issue5/Number_Param_Types "Number-Parameterized Types"] in the [http://www.haskell.org/haskellwiki/The_Monad.Reader/Issue5 fifth issue] of [http://themonadreader.wordpress.com/ The Monad Reader].<br />
There is an implementation in the {{HackagePackage|id=type-level}} package, but unfortunately the arithmetic is really slow, because in fact it simulates Peano arithmetic with decimal numbers.<br />
<br />
== Library support ==<br />
<br />
Robert Dockins has gone as far as to write<br />
a [http://article.gmane.org/gmane.comp.lang.haskell.general/13206 library]<br />
for type level arithmetic, supporting the following operations on type<br />
level naturals: addition, subtraction, multiplication, division,<br />
remainder, GCD, and also contains the following predicates: test for<br />
zero, test for equality and < > <= >=<br />
<br />
This library uses a binary representation and can handle numbers at<br />
the order of 10^15 (at least). It also contains a test suite to help<br />
validate the somewhat unintuitive algorithms.<br />
<br />
More libraries:<br />
<br />
* {{HackagePackage|id=type-level}} Natural numbers in decimal representation using functional dependencies and Template Haskell. However arithmetic is performed in a unary way and thus it is quite slow.<br />
* {{HackagePackage|id=type-level-tf}} Similar to the type-level package (also in speed) but uses type families instead of functional dependencies and uses the same module names as the type-level package. Thus module name clashes are warranted if you have to use both packages.<br />
* {{HackagePackage|id=type-level-natural-number}} and related packages. A collection of packages where the simplest one is even Haskell2010.<br />
* {{HackagePackage|id=tfp}} Decimal representation, Type families, Template Haskell.<br />
* {{HackagePackage|id=typical}} Binary numbers and functional dependencies.<br />
* {{HackagePackage|id=type-unary}} Unary representation and type families.<br />
* {{HackagePackage|id=numtype}}, {{HackagePackage|id=numtype-tf}} Unary representation and functional dependencies and type families, respectively.<br />
<br />
== More type hackery ==<br />
<br />
Not to be outdone, Oleg Kiselyov has <br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/13223 written]<br />
on invertible, terminating, 3-place addition, multiplication,<br />
exponentiation relations on type-level Peano numerals, where any two<br />
operands determine the third. He also shows the invertible factorial<br />
relation. Thus providing all common arithmetic operations on Peano<br />
numerals, including n-base discrete logarithm, n-th root, and the<br />
inverse of factorial. The inverting method can work with any<br />
representation of (type-level) numerals, binary or decimal.<br />
<br />
Oleg says, "The implementation of RSA on the type level is left for future work".<br />
<br />
== Djinn ==<br />
<br />
Somewhat related is Lennart Augustsson's tool <br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/12747 Djinn], a theorem<br />
prover/coding wizard, that generates Haskell code from a given Haskell<br />
type declaration.<br />
<br />
Djinn interprets a Haskell type as a logic formula using<br />
[http://en.wikipedia.org/wiki/Curry-Howard the Curry-Howard isomorphism]<br />
and then a decision procedure for Intuitionistic Propositional Calculus.<br />
<br />
== An Advanced Example : Type-Level Quicksort ==<br />
<br />
An advanced example: quicksort on the type level.<br />
<br />
Here is a complete example of advanced type level computation, kindly<br />
provided by Roman Leshchinskiy. For further information consult Thomas<br />
Hallgren's 2001 paper <br />
[http://www.cs.chalmers.se/~hallgren/Papers/wm01.html Fun with Functional Dependencies]. <br />
<br />
<haskell><br />
module Sort where<br />
<br />
-- natural numbers<br />
data Zero<br />
data Succ a<br />
<br />
-- booleans<br />
data True<br />
data False<br />
<br />
-- lists<br />
data Nil<br />
data Cons a b<br />
<br />
-- shortcuts<br />
type One = Succ Zero<br />
type Two = Succ One<br />
type Three = Succ Two<br />
type Four = Succ Three<br />
<br />
-- example list<br />
list1 :: Cons Three (Cons Two (Cons Four (Cons One Nil)))<br />
list1 = undefined<br />
<br />
-- utilities<br />
numPred :: Succ a -> a<br />
numPred = const undefined<br />
<br />
class Number a where<br />
numValue :: a -> Int<br />
<br />
instance Number Zero where<br />
numValue = const 0<br />
instance Number x => Number (Succ x) where<br />
numValue x = numValue (numPred x) + 1<br />
<br />
numlHead :: Cons a b -> a<br />
numlHead = const undefined<br />
<br />
numlTail :: Cons a b -> b<br />
numlTail = const undefined<br />
<br />
class NumList l where<br />
listValue :: l -> [Int]<br />
<br />
instance NumList Nil where<br />
listValue = const []<br />
instance (Number x, NumList xs) => NumList (Cons x xs) where<br />
listValue l = numValue (numlHead l) : listValue (numlTail l)<br />
<br />
-- comparisons<br />
data Less<br />
data Equal<br />
data Greater<br />
<br />
class Cmp x y c | x y -> c<br />
<br />
instance Cmp Zero Zero Equal<br />
instance Cmp Zero (Succ x) Less<br />
instance Cmp (Succ x) Zero Greater<br />
instance Cmp x y c => Cmp (Succ x) (Succ y) c<br />
<br />
-- put a value into one of three lists according to a pivot element<br />
class Pick c x ls eqs gs ls' eqs' gs' | c x ls eqs gs -> ls' eqs' gs'<br />
instance Pick Less x ls eqs gs (Cons x ls) eqs gs<br />
instance Pick Equal x ls eqs gs ls (Cons x eqs) gs<br />
instance Pick Greater x ls eqs gs ls eqs (Cons x gs)<br />
<br />
-- split a list into three parts according to a pivot element<br />
class Split n xs ls eqs gs | n xs -> ls eqs gs<br />
instance Split n Nil Nil Nil Nil<br />
instance (Split n xs ls' eqs' gs',<br />
Cmp x n c,<br />
Pick c x ls' eqs' gs' ls eqs gs) =><br />
Split n (Cons x xs) ls eqs gs<br />
<br />
listSplit :: Split n xs ls eqs gs => (n, xs) -> (ls, eqs, gs)<br />
listSplit = const (undefined, undefined, undefined)<br />
<br />
-- zs = xs ++ ys<br />
class App xs ys zs | xs ys -> zs<br />
instance App Nil ys ys<br />
instance App xs ys zs => App (Cons x xs) ys (Cons x zs)<br />
<br />
-- zs = xs ++ [n] ++ ys<br />
-- this is needed because<br />
--<br />
-- class CCons x xs xss | x xs -> xss<br />
-- instance CCons x xs (Cons x xs)<br />
--<br />
-- doesn't work<br />
<br />
class App' xs n ys zs | xs n ys -> zs<br />
instance App' Nil n ys (Cons n ys)<br />
instance (App' xs n ys zs) => App' (Cons x xs) n ys (Cons x zs)<br />
<br />
-- quicksort<br />
class QSort xs ys | xs -> ys<br />
instance QSort Nil Nil<br />
instance (Split x xs ls eqs gs,<br />
QSort ls ls',<br />
QSort gs gs',<br />
App eqs gs' geqs,<br />
App' ls' x geqs ys) =><br />
QSort (Cons x xs) ys<br />
<br />
listQSort :: QSort xs ys => xs -> ys<br />
listQSort = const undefined<br />
</haskell><br />
<br />
And we need to be able to run this somehow, in the typechecker. So fire up ghci:<br />
<br />
<haskell><br />
> :t listQSort list1<br />
Cons<br />
(Succ Zero)<br />
(Cons (Succ One) (Cons (Succ Two) (Cons (Succ Three) Nil)))<br />
</haskell><br />
<br />
== A Really Advanced Example : Type-Level Lambda Calculus ==<br />
<br />
Again, thanks to Roman Leshchinskiy, we present a simple lambda calculus<br />
encoded in the type system (and with non-terminating typechecking fun!)<br />
<br />
Below is an example which encodes a stripped-down version of the lambda<br />
calculus (with only one variable):<br />
<br />
<haskell><br />
{-# OPTIONS -fglasgow-exts #-}<br />
data X<br />
data App t u<br />
data Lam t<br />
<br />
class Subst s t u | s t -> u<br />
instance Subst X u u<br />
instance (Subst s u s', Subst t u t') => Subst (App s t) u (App s' t')<br />
instance Subst (Lam t) u (Lam t)<br />
<br />
class Apply s t u | s t -> u<br />
instance (Subst s t u, Eval u u') => Apply (Lam s) t u'<br />
<br />
class Eval t u | t -> u<br />
instance Eval X X<br />
instance Eval (Lam t) (Lam t)<br />
instance (Eval s s', Apply s' t u) => Eval (App s t) u<br />
</haskell><br />
<br />
Now, lets evaluate some lambda expressions:<br />
<br />
<haskell><br />
> :t undefined :: Eval (App (Lam X) X) u => u<br />
undefined :: Eval (App (Lam X) X) u => u :: X<br />
</haskell><br />
<br />
Ok good, and:<br />
<br />
<haskell><br />
> :t undefined :: Eval (App (Lam (App X X)) (Lam (App X X)) ) u => u<br />
^CInterrupted.<br />
</haskell><br />
<br />
diverges ;)<br />
<br />
== Turing-completeness ==<br />
<br />
It's possible to embed the Turing-complete [[Type_SK|SK combinator calculus]] at the type level.<br />
<br />
== Theory ==<br />
<br />
See also [[dependent type]] theory.<br />
<br />
== Practice ==<br />
<br />
[[Extensible record]]s (which are used e.g. in type safe, declarative [[relational algebra]] approaches to [[Libraries and tools/Database interfaces|database management]])<br />
<br />
[[Category:Idioms]]<br />
[[Category:Mathematics]]<br />
[[Category:Type-level programming]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=GHC/Typed_holes&diff=57660GHC/Typed holes2014-03-12T21:10:06Z<p>Heisenbug: adapt to new terminology</p>
<hr />
<div>[[Category:GHC|Type system]]<br />
<span style='font-size: x-large; font-weight: bold'>Typed holes in GHC.</span><br />
<br />
Typed holes are a powerful feature in GHC inspired by [http://wiki.portal.chalmers.se/agda/pmwiki.php Agda]. But what are typed holes, and how do they help us write code?<br />
<br />
(This page was taken from a 'tutorial' I wrote of this feature [http://www.reddit.com/r/haskell/comments/10u7xr/ghc_head_now_features_agdalike_holes/c6gr9qe on Reddit].)<br />
<br />
== Introduction ==<br />
<br />
Sometimes, when writing programs, we tend to use lots of polymorphic types. That's good! We can reuse those pieces, thanks to the types. But it can be difficult sometimes when writing a program to see how the polymorphic types should exactly fit together, given the things in scope.<br />
<br />
Would it not be nice if we could have the compiler tell us the types of everything in scope? It'd be much easier to see how we can 'fit' them together like puzzle pieces.<br />
<br />
This is the purpose of a hole: it has similar semantics to <tt>undefined</tt>, in that evaluating it is an error (you can replace all holes with <tt>undefined</tt>, and vice versa, and nothing has changed: you may even say <tt>undefined</tt> is just a really crappy, useless hole!) But it's special in that when GHC encounters a hole during compilation it will tell you what type needs to be there in place of the hole, for the type-checker to be OK with the definition. It will also show you the types of all the bindings in scope, to assist you in figuring out the problem.<br />
<br />
This feature was implemented by Simon Peyton Jones, Sean Leather and Thijs Alkemade, and is scheduled to be released with GHC 7.8.1 (likely released sometime 2014.) It is enabled by default.<br />
<br />
== Motivating example ==<br />
<br />
Let us consider the definition of a Free monad:<br />
<br />
<haskell><br />
data Free f a<br />
= Pure a<br />
| Free (f (Free f a))<br />
</haskell><br />
<br />
A free monad coupled with an underlying <tt>Functor f</tt>. We would like to write the Monad instance for <tt>Free f</tt>.<br />
<br />
We begin by writing the trivial cases:<br />
<br />
<haskell><br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = ... -- I'm confused!<br />
</haskell><br />
<br />
... but we're a little stumped on how to write the final case. Let's have the compiler help us do this.<br />
<br />
== Writing 'instance Monad (Free f)' ==<br />
<br />
Let's go ahead and shove all of this in a file. For the final case of the <tt>Monad (Free f)</tt> instance, we will place a hole in the definition, which is designated by the same syntax for wildcard patterns, <tt>_</tt><br />
<br />
<haskell><br />
module FreeMonad where<br />
<br />
data Free f a<br />
= Pure a<br />
| Free (f (Free f a))<br />
<br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = Free _<br />
</haskell><br />
<br />
Now let's load that into GHCi. We should see something that looks like this:<br />
<br />
<code><pre><br />
$ ghci FreeMonad.hs<br />
[1 of 1] Compiling Main ( holes.hs, interpreted )<br />
<br />
FreeMonad.hs:11:23: Warning:<br />
Found hole `_' with type f (Free f b)<br />
Where: `f' is a rigid type variable bound by<br />
the instance declaration at holes.hs:26:10<br />
`b' is a rigid type variable bound by<br />
the type signature for<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
at FreeMonad.hs:10:10<br />
Relevant bindings include<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
(bound at FreeMonad.hs:11:3)<br />
f :: f (Free f a) (bound at FreeMonad.hs:11:8)<br />
g :: a -> Free f b (bound at FreeMonad.hs:11:14)<br />
In the first argument of `Free', namely `_'<br />
In the expression: Free (_)<br />
In an equation for `>>=': (Free f) >>= g = Free (_)<br />
Ok, modules loaded: Main.<br />
*Main> <br />
</pre></code><br />
<br />
Let's look at the error, and what the hole should look like (first line of the error):<br />
<br />
<code><pre><br />
Found hole `_' with type f (Free f b)<br />
</pre></code><br />
<br />
OK, so I need some value of type <tt>f (Free f b)</tt> to put there. I don't know how to get that. But let's look at what's in scope:<br />
<br />
<code><pre><br />
Relevant bindings include<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
(bound at holes.hs:28:3)<br />
f :: f (Free f a) (bound at holes.hs:29:8)<br />
g :: a -> Free f b (bound at holes.hs:29:14)<br />
In the first argument of `Free', namely `_'<br />
</pre></code><br />
<br />
OK, so I have 3 values directly surrounding me at my disposal: <tt>f</tt>, <tt>g</tt>, and <tt>(>>=)</tt>. I have a <tt>f :: f (Free f a)</tt> in scope, and that's almost what I need. I just need to turn the inner <tt>Free f a</tt> into a <tt>Free f b</tt>. And that's what fmap does for functors! And I don't know what the functor <tt>f</tt> is anyway, so clearly I need to <tt>fmap</tt> the value before anything else. Let's do that and use a hole to tell us where to go next:<br />
<br />
<code><pre><br />
instance Monad ... where<br />
...<br />
Free f >>= g = Free (fmap _ f)<br />
</pre></code><br />
<br />
Now we get from the compiler:<br />
<br />
<code><br />
Found hole `_' with type Free f a -> Free f b<br />
</code><br />
<br />
OK, so now we just need some function with type <tt>Free f a -> Free f b</tt>. Let's look at what's in scope. We can quickly see that <tt>(>>=)</tt> has the type we want if we partially apply it. And <tt>g</tt> has just the type we need for that partial application! Equationally:<br />
<br />
<code><pre><br />
(>>=) :: Free f a -> (a -> Free f b) -> Free f b<br />
g :: a -> Free f b<br />
</pre></code><br />
<br />
Ergo:<br />
<br />
<code><pre><br />
(\x -> x >>= g) :: Free f a -> Free f b<br />
</pre></code><br />
<br />
So the resulting instance is:<br />
<br />
<code><pre><br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = Free (fmap (>>= g) f)<br />
</pre></code><br />
<br />
== Notes on parametricity, free theorems and Agda ==<br />
<br />
These examples hint at what people mean when they say they use the type system to drive development: it can help write your code, too!<br />
<br />
This is of course very powerful for general, polymorphic types like above, because a polymorphic function may only be written so many ways. In fact, the above definition is the only legitimate <tt>Monad</tt> instance for <tt>Free</tt>!<br />
<br />
A polymorphic type variable says what you cannot do to it: touch! You can't break the parametric nature of it by scrutinizing the variable in any way. A useful implementation of a polymorphic function has a small 'design space', naturally. It is not so, when defining monomorphic functions. A function like <tt>f :: Int -> Double</tt> could have many possible definitions, but we can always be sure for example, that <tt>f :: a -> a</tt> only has one valid definition, or that if <tt>f :: [a] -> [a]</tt>, then 'trivially' we can see that <tt>f [] = []</tt> must hold as a law.<br />
<br />
This notion of "what information may be calculated based on the type" like we're doing here can be formalized to what we call 'Free Theorems', pioneered by Philip Wadler in his paper '[http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf Theorems for Free!]'<br />
<br />
Free theorems fall out of the parametricity theorem (also called Reynolds' abstraction theorem,) which essentially states how polymorphic types relate to each other. Free theorems just state that, given a polymorphic type, it's possible to derive useful theorems and laws, based only on that type alone (so if <tt>f :: [a] -> [a]</tt> as we said earlier, then we get the free theorem <tt>f [] = []</tt> by definition - try writing that case another way! You can't!)<br />
<br />
At this point, you're getting into much deeper territory, but I say all this because you have probably intuitively thought some of these things, when writing polymorphic functions yourself - that you must write them in such a way that the terms are all properly abstracted over correctly. This kind of design 'forces' only a few definitions to be possible.<br />
<br />
Holes for GHC were inspired by the equivalent feature in its (twice removed) sister language, [http://wiki.portal.chalmers.se/agda/pmwiki.php Agda]. Holes are considerably more powerful in Agda, mostly due to the fact it is total, the compiler infers less, and thus Agda programs are <i>rich</i> with evidence, giving witness to many facts the compiler can use. As a result, it can derive more code for you. In particular, Agda can literally <i>write</i> your code based on holes. It's able to do things like write case-analysis' for you, based only on type structure, and what's in scope, and discharge all the 'trivial' cases. You do this in emacs, in one or two keystrokes. It's essentially a semi-automated feedback loop for development, and it makes sense because the tool is really working with a meaningful model of your code, only in sensible ways that type-check. It's great.<br />
<br />
There is not necessarily a reason why this could not exist for e.g. the Emacs mode for Haskell. Just because Haskell is not total, doesn't mean we couldn't calculate useful code based on the type - it is just much harder, especially considering the multitudes of features and extensions GHC supports.<br />
<br />
* When I say 'legitimate' or 'useful', I mean, 'modulo divergent definitions.' Because Haskell is not total, it is possible to write divergent terms like <tt>let x = x in x</tt>, and the type of this expression is <tt>forall a. a</tt>, meaning I can prove <i>anything</i> with it. In the domain of Haskell semantics, this expression is in fact equivalent to <tt>undefined</tt> as well, because all bottoms are equal. I can prove that Blue is Green this way, or that Freedom is Slavery - I can inhabit any type, using these nonsensical terms. Logistically, you could say Haskell terms are complete, but not coherent/consistent. But divergent definitions here are not very legitimate, interesting, or useful, obviously, so ignore them (cue, [http://www.cse.chalmers.se/~nad/publications/danielsson-et-al-popl2006.html "Fast and Loose reasoning is morally correct."])</div>Heisenbughttps://wiki.haskell.org/index.php?title=GHC/Typed_holes&diff=57658GHC/Typed holes2014-03-12T21:07:12Z<p>Heisenbug: Heisenbug moved page GHC/TypeHoles to GHC/TypedHoles: terminology changed</p>
<hr />
<div>[[Category:GHC|Type system]]<br />
<span style='font-size: x-large; font-weight: bold'>Type holes in GHC.</span><br />
<br />
Type holes are a powerful feature in GHC inspired by [http://wiki.portal.chalmers.se/agda/pmwiki.php Agda]. But what are type holes, and how do they help us write code?<br />
<br />
(This page was taken from a 'tutorial' I wrote of this feature [http://www.reddit.com/r/haskell/comments/10u7xr/ghc_head_now_features_agdalike_holes/c6gr9qe on Reddit].)<br />
<br />
== Introduction ==<br />
<br />
Sometimes, when writing programs, we tend to use lots of polymorphic types. That's good! We can reuse those pieces, thanks to the types. But it can be difficult sometimes when writing a program to see how the polymorphic types should exactly fit together, given the things in scope.<br />
<br />
Would it not be nice if we could have the compiler tell us the types of everything in scope? It'd be much easier to see how we can 'fit' them together like puzzle pieces.<br />
<br />
This is the purpose of a hole: it has similar semantics to <tt>undefined</tt>, in that evaluating it is an error (you can replace all holes with <tt>undefined</tt>, and vice versa, and nothing has changed: you may even say <tt>undefined</tt> is just a really crappy, useless hole!) But it's special in that when GHC encounters a hole during compilation it will tell you what type needs to be there in place of the hole, for the type-checker to be OK with the definition. It will also show you the types of all the bindings in scope, to assist you in figuring out the problem.<br />
<br />
This feature was implemented by Simon Peyton Jones, Sean Leather and Thijs Alkemade, and is scheduled to be released with GHC 7.8.1 (likely released sometime 2014.) It is enabled by default.<br />
<br />
== Motivating example ==<br />
<br />
Let us consider the definition of a Free monad:<br />
<br />
<haskell><br />
data Free f a<br />
= Pure a<br />
| Free (f (Free f a))<br />
</haskell><br />
<br />
A free monad coupled with an underlying <tt>Functor f</tt>. We would like to write the Monad instance for <tt>Free f</tt>.<br />
<br />
We begin by writing the trivial cases:<br />
<br />
<haskell><br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = ... -- I'm confused!<br />
</haskell><br />
<br />
... but we're a little stumped on how to write the final case. Let's have the compiler help us do this.<br />
<br />
== Writing 'instance Monad (Free f)' ==<br />
<br />
Let's go ahead and shove all of this in a file. For the final case of the <tt>Monad (Free f)</tt> instance, we will place a hole in the definition, which is designated by the same syntax for wildcard patterns, <tt>_</tt><br />
<br />
<haskell><br />
module FreeMonad where<br />
<br />
data Free f a<br />
= Pure a<br />
| Free (f (Free f a))<br />
<br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = Free _<br />
</haskell><br />
<br />
Now let's load that into GHCi. We should see something that looks like this:<br />
<br />
<code><pre><br />
$ ghci FreeMonad.hs<br />
[1 of 1] Compiling Main ( holes.hs, interpreted )<br />
<br />
FreeMonad.hs:11:23: Warning:<br />
Found hole `_' with type f (Free f b)<br />
Where: `f' is a rigid type variable bound by<br />
the instance declaration at holes.hs:26:10<br />
`b' is a rigid type variable bound by<br />
the type signature for<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
at FreeMonad.hs:10:10<br />
Relevant bindings include<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
(bound at FreeMonad.hs:11:3)<br />
f :: f (Free f a) (bound at FreeMonad.hs:11:8)<br />
g :: a -> Free f b (bound at FreeMonad.hs:11:14)<br />
In the first argument of `Free', namely `_'<br />
In the expression: Free (_)<br />
In an equation for `>>=': (Free f) >>= g = Free (_)<br />
Ok, modules loaded: Main.<br />
*Main> <br />
</pre></code><br />
<br />
Let's look at the error, and what the hole should look like (first line of the error):<br />
<br />
<code><pre><br />
Found hole `_' with type f (Free f b)<br />
</pre></code><br />
<br />
OK, so I need some value of type <tt>f (Free f b)</tt> to put there. I don't know how to get that. But let's look at what's in scope:<br />
<br />
<code><pre><br />
Relevant bindings include<br />
>>= :: Free f a -> (a -> Free f b) -> Free f b<br />
(bound at holes.hs:28:3)<br />
f :: f (Free f a) (bound at holes.hs:29:8)<br />
g :: a -> Free f b (bound at holes.hs:29:14)<br />
In the first argument of `Free', namely `_'<br />
</pre></code><br />
<br />
OK, so I have 3 values directly surrounding me at my disposal: <tt>f</tt>, <tt>g</tt>, and <tt>(>>=)</tt>. I have a <tt>f :: f (Free f a)</tt> in scope, and that's almost what I need. I just need to turn the inner <tt>Free f a</tt> into a <tt>Free f b</tt>. And that's what fmap does for functors! And I don't know what the functor <tt>f</tt> is anyway, so clearly I need to <tt>fmap</tt> the value before anything else. Let's do that and use a hole to tell us where to go next:<br />
<br />
<code><pre><br />
instance Monad ... where<br />
...<br />
Free f >>= g = Free (fmap _ f)<br />
</pre></code><br />
<br />
Now we get from the compiler:<br />
<br />
<code><br />
Found hole `_' with type Free f a -> Free f b<br />
</code><br />
<br />
OK, so now we just need some function with type <tt>Free f a -> Free f b</tt>. Let's look at what's in scope. We can quickly see that <tt>(>>=)</tt> has the type we want if we partially apply it. And <tt>g</tt> has just the type we need for that partial application! Equationally:<br />
<br />
<code><pre><br />
(>>=) :: Free f a -> (a -> Free f b) -> Free f b<br />
g :: a -> Free f b<br />
</pre></code><br />
<br />
Ergo:<br />
<br />
<code><pre><br />
(\x -> x >>= g) :: Free f a -> Free f b<br />
</pre></code><br />
<br />
So the resulting instance is:<br />
<br />
<code><pre><br />
instance Functor f => Monad (Free f) where<br />
return a = Pure a<br />
Pure a >>= f = f a<br />
Free f >>= g = Free (fmap (>>= g) f)<br />
</pre></code><br />
<br />
== Notes on parametricity, free theorems and Agda ==<br />
<br />
These examples hint at what people mean when they say they use the type system to drive development: it can help write your code, too!<br />
<br />
This is of course very powerful for general, polymorphic types like above, because a polymorphic function may only be written so many ways. In fact, the above definition is the only legitimate <tt>Monad</tt> instance for <tt>Free</tt>!<br />
<br />
A polymorphic type variable says what you cannot do to it: touch! You can't break the parametric nature of it by scrutinizing the variable in any way. A useful implementation of a polymorphic function has a small 'design space', naturally. It is not so, when defining monomorphic functions. A function like <tt>f :: Int -> Double</tt> could have many possible definitions, but we can always be sure for example, that <tt>f :: a -> a</tt> only has one valid definition, or that if <tt>f :: [a] -> [a]</tt>, then 'trivially' we can see that <tt>f [] = []</tt> must hold as a law.<br />
<br />
This notion of "what information may be calculated based on the type" like we're doing here can be formalized to what we call 'Free Theorems', pioneered by Philip Wadler in his paper '[http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf Theorems for Free!]'<br />
<br />
Free theorems fall out of the parametricity theorem (also called Reynolds' abstraction theorem,) which essentially states how polymorphic types relate to each other. Free theorems just state that, given a polymorphic type, it's possible to derive useful theorems and laws, based only on that type alone (so if <tt>f :: [a] -> [a]</tt> as we said earlier, then we get the free theorem <tt>f [] = []</tt> by definition - try writing that case another way! You can't!)<br />
<br />
At this point, you're getting into much deeper territory, but I say all this because you have probably intuitively thought some of these things, when writing polymorphic functions yourself - that you must write them in such a way that the terms are all properly abstracted over correctly. This kind of design 'forces' only a few definitions to be possible.<br />
<br />
Holes for GHC were inspired by the equivalent feature in its (twice removed) sister language, [http://wiki.portal.chalmers.se/agda/pmwiki.php Agda]. Holes are considerably more powerful in Agda, mostly due to the fact it is total, the compiler infers less, and thus Agda programs are <i>rich</i> with evidence, giving witness to many facts the compiler can use. As a result, it can derive more code for you. In particular, Agda can literally <i>write</i> your code based on holes. It's able to do things like write case-analysis' for you, based only on type structure, and what's in scope, and discharge all the 'trivial' cases. You do this in emacs, in one or two keystrokes. It's essentially a semi-automated feedback loop for development, and it makes sense because the tool is really working with a meaningful model of your code, only in sensible ways that type-check. It's great.<br />
<br />
There is not necessarily a reason why this could not exist for e.g. the Emacs mode for Haskell. Just because Haskell is not total, doesn't mean we couldn't calculate useful code based on the type - it is just much harder, especially considering the multitudes of features and extensions GHC supports.<br />
<br />
* When I say 'legitimate' or 'useful', I mean, 'modulo divergent definitions.' Because Haskell is not total, it is possible to write divergent terms like <tt>let x = x in x</tt>, and the type of this expression is <tt>forall a. a</tt>, meaning I can prove <i>anything</i> with it. In the domain of Haskell semantics, this expression is in fact equivalent to <tt>undefined</tt> as well, because all bottoms are equal. I can prove that Blue is Green this way, or that Freedom is Slavery - I can inhabit any type, using these nonsensical terms. Logistically, you could say Haskell terms are complete, but not coherent/consistent. But divergent definitions here are not very legitimate, interesting, or useful, obviously, so ignore them (cue, [http://www.cse.chalmers.se/~nad/publications/danielsson-et-al-popl2006.html "Fast and Loose reasoning is morally correct."])</div>Heisenbughttps://wiki.haskell.org/index.php?title=GHC/TypeHoles&diff=57659GHC/TypeHoles2014-03-12T21:07:12Z<p>Heisenbug: Heisenbug moved page GHC/TypeHoles to GHC/TypedHoles: terminology changed</p>
<hr />
<div>#REDIRECT [[GHC/TypedHoles]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=LGtk/Semantics&diff=56122LGtk/Semantics2013-06-03T10:32:58Z<p>Heisenbug: typo</p>
<hr />
<div>The semantics of LGtk is given by a reference implementation.<br />
The reference implementation is given in three stages: lenses, references and effects.<br />
<br />
== Lenses ==<br />
<br />
LGtk uses simple lenses defined in the data-lens package:<br />
<br />
<haskell><br />
newtype Lens a b = Lens { runLens :: a -> Store b a }<br />
</haskell><br />
<br />
This data type is isomorphic to <hask>(a -> b, b -> a -> a)</hask>, the well-know lens data type. The isomorphism is established by the following operations:<br />
<br />
<haskell><br />
getL :: Lens a b -> a -> b<br />
</haskell><br />
<br />
<haskell><br />
setL :: Lens a b -> b -> a -> a<br />
</haskell><br />
<br />
<haskell><br />
lens :: (a -> b) -> (b -> a -> a) -> Lens a b<br />
</haskell><br />
<br />
=== Lens laws ===<br />
<br />
The three well-known laws for lenses:<br />
<br />
* get-set: <hask>setL k (getL k a) a</hask> === <hask>a</hask><br />
* set-get: <hask>getL k (setL k b a)</hask> === <hask>b</hask><br />
* set-set: <hask>setL k b2 (setL k b1 a)</hask> === <hask>setL k b2 a</hask><br />
<br />
Impure lenses, i.e. lenses which<br />
break lens laws are allowed in certain places. Those places are explicitly marked and explained in this overview. (TODO)<br />
<br />
== References ==<br />
<br />
=== Motivation ===<br />
<br />
Let <hask>s :: *</hask> be a type.<br />
<br />
Consider the three types <hask>Lens s :: * -> *</hask>, <hask>State s :: * -> *</hask>, <hask>Reader s :: * -> *</hask> with their type class instances and operations. This structure is useful in practice ([http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html see this use case]).<br />
<br />
We have the following goals:<br />
<br />
* Define a structure similar to <hask>(Lens s, State s, Reader s)</hask> in which <hask>s</hask> is not accessible.<br />
* Extend the defined structure with operations which help modularity.<br />
<br />
The first goal is justified by our solution for the second goal. The second goal is justified by the fact that a global state is not convenient to maintain explicitly.<br />
<br />
=== Types ===<br />
<br />
We keep the types <hask>(Lens s, State s, Reader s)</hask> but give them a more restricted API. There are several ways to do this in Haskell. LGtk defines type classes with associated types, but that is just a technical detail.<br />
<br />
Instead of giving a concrete implementation in Haskell, suppose that<br />
<br />
* <hask>s</hask> is a fixed arbitrary type,<br />
* <hask>Ref :: * -> *</hask> ~ <hask>Lens s</hask>; '''references''' are lenses from <hask>s</hask> to the type of the referred value,<br />
* <hask>R :: * -> *</hask> ~ <hask>Reader s</hask>; the '''reference reading monad''' is the reader monad over <hask>s</hask>,<br />
* <hask>M :: * -> *</hask> ~ <hask>State s</hask>; the '''reference modifying monad''' is the state monad over <hask>s</hask>.<br />
<br />
The three equality constraints are not exposed in the API, of course.<br />
<br />
=== Operations ===<br />
<br />
Exposed operations of <hask>Ref</hask>, <hask>R</hask> and <hask>M</hask> are the following:<br />
<br />
* The <hask>Monad</hask> instance of <hask>R</hask> and <hask>M</hask><br />
<br />
* The monad morphism between <hask>R</hask> and <hask>M</hask><br />
<br />
<haskell><br />
liftReadPart :: R a -> M a<br />
liftReadPart = gets . runReader<br />
</haskell><br />
<br />
* Reference read<br />
<br />
<haskell><br />
readRef :: Ref a -> R a<br />
readRef = reader . getL<br />
</haskell><br />
<br />
* Reference write<br />
<br />
<haskell><br />
writeRef :: Ref a -> a -> M ()<br />
writeRef = modify . setL r<br />
</haskell><br />
<br />
* Lens application on a reference<br />
<br />
<haskell><br />
lensMap :: Lens a b -> Ref a -> Ref b<br />
lensMap = (.)<br />
</haskell><br />
<br />
* Reference join<br />
<br />
<haskell><br />
joinRef :: R (Ref a) -> Ref a<br />
joinRef = Lens . join . (runLens .) . runReader <br />
</haskell><br />
<br />
* The unit reference<br />
<br />
<haskell><br />
unitRef :: Ref ()<br />
unitRef = lens (const ()) (const id) <br />
</haskell><br />
<br />
Note that the identity lens is '''not''' a reference because that would leak the program state <hask>s</hask>.<br />
<br />
==== Reference laws ====<br />
<br />
From lens laws we can derive the following reference laws:<br />
<br />
* <hask>liftReadPart (readRef r) >>= writeRef r</hask> === <hask>return ()</hask><br />
<br />
* <hask>writeRef r a >> liftReadPart (readRef r)</hask> === <hask>return a</hask><br />
<br />
* <hask>writeRef r a >> writeRef r a'</hask> === <hask>writeRef r a'</hask><br />
<br />
Additional laws derived from the properties of the <hask>Reader</hask> monad:<br />
<br />
* <hask>liftReadPart m >> return ()</hask> === <hask>return ()</hask><br />
<br />
* <hask>liftM2 (,) (liftReadPart m) (liftReadPart m)</hask> === <hask>liftM (\a -> (a, a)) (liftReadPart m)</hask><br />
<br />
=== Reference creation ===<br />
<br />
New reference creation is our first operation wich helps modularity.<br />
<br />
New reference creation with a given initial value extends the state. For example, if the state is <hask>(1, 'c') :: (Int, Char)</hask>, extending the state with <hask>True :: Bool</hask> would yield the state <hask>(True, (1, 'c')) :: (Bool, (Int, Char))</hask>.<br />
<br />
We could model the type change of the state with an [http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Monad-Indexed.html indexed monad], but that would complicate both the API and the implementation too.<br />
<br />
Instead of changing the type of the state, we use an '''extensible state''', an abstract data type <hask>S</hask> with the operations<br />
<br />
<haskell><br />
empty :: S<br />
</haskell><br />
<br />
<haskell><br />
extend :: a -> State S (Lens S a)<br />
</haskell><br />
<br />
such that the following laws hold:<br />
<br />
* <hask>extend v >> return ()</hask> === <hask>return ()</hask><br />
<br />
* <hask>extend v >>= liftReadPart . readRef</hask> === <hask>return v</hask><br />
<br />
The first law sais that <hask>extend</hask> has no side-effect, i.e. extending the state does not change the values of existing references. The second law sais that extending the state with value <hask>v</hask> creates a reference with inital value <hask>v</hask>.<br />
<br />
'''Question:''' Is there a data type with such operations?<br />
<br />
The answer is '''yes''', but we should guarantee linear usage of the state. The (constructive) existence proof is given in the next section.<br />
<br />
Linear usage of state is guaranteed with the above refereces API (check the definitions), which means that we have a solution.<br />
<br />
Can this extensible state be implemented efficiently? Although this question is not relevant for the semantics, we will see that there is an efficient implementation with <hask>MVar</hask>s (TODO).<br />
<br />
==== Reference creation API ====<br />
<br />
Let <hask>S</hask> be an extensible state as specified above.<br />
Let <hask>s</hask> = <hask>S</hask> in the definition of references.<br />
<br />
* <hask>C :: (* -> *) -> * -> *</hask> ~ <hask>StateT S</hask>, the '''reference creating monad''', is the state monad transformer over <hask>S</hask>.<br />
<br />
The equality constraint is not exposed in the API.<br />
The following functions are exposed:<br />
<br />
* New reference creation<br />
<br />
<haskell><br />
newRef :: Monad m => a -> C m (Ref a)<br />
newRef = mapStateT (return . runIdentity) . extend<br />
</haskell><br />
<br />
* Lift reference modifying operations<br />
<br />
<haskell><br />
liftWrite :: Monad m => M a -> C m a<br />
liftWrite = mapStateT (return . runIdentity)<br />
</haskell><br />
<br />
* Derived <hask>MonadTrans</hask> instance of <hask>C</hask> to be able to lift operations in the <hask>m</hask> monad.<br />
<br />
Note that <hask>C</hask> is parameterized by a monad because in this way it is easier to add other effects later.<br />
<br />
=== Running ===<br />
<br />
The API is completed with the following function:<br />
<br />
* Run the reference creation monad<br />
<br />
<haskell><br />
runC :: Monad m => C m a -> m a<br />
runC x = runStateT x empty<br />
</haskell><br />
<br />
=== Lens-chains ===<br />
<br />
==== Motivation ====<br />
<br />
With <hask>newRef</hask> the program state can be extended in an independent way (the new state piece is independent from the others). This is not always enough for modular design.<br />
<br />
Suppose that we have a reference <hask>r :: Ref (Maybe Int)</hask> and we would like to expose an editor of it to the user. The exposed editor would contain a checkbox and an integer entry field. If the checkbox is unchecked, the value of <hask>r</hask> should be <hask>Nothing</hask>, otherwise it should be <hask>Just i</hask> where <hask>i</hask> is the value of the entry field.<br />
<br />
The problem is that we cannot remember the value of the entry field if the checkbox is unchecked! Lens-chains give a nice solution to this problem.<br />
<br />
==== Low-level API ====<br />
<br />
Let's begin with the API. Suppose that we have an abstract data type <hask>S</hask> with the following operations:<br />
<br />
<haskell><br />
empty :: S<br />
</haskell><br />
<br />
<haskell><br />
extend' :: Lens S b -> Lens a b -> a -> State S (Lens S a)<br />
</haskell><br />
<br />
such that the following laws hold:<br />
<br />
* Law 1: <hask>extend' r k a0 >> return ()</hask> === <hask>return ()</hask><br />
<br />
* Law 2: <hask>liftM (k .) $ extend' r k a0</hask> === <hask>return r</hask> <br />
<br />
* Law 3: <hask>extend' r k a0 >>= readRef</hask> === <hask>readRef r >>= setL k a0</hask><br />
<br />
Law 1 sais that <hask>extend'</hask> has no side-effect. Law 2 sais that <hask>k</hask> applied on the result of <hask>extend' r k a0</hask> behaves as <hask>r</hask>. Law 3 defines the initial value of the newly defined reference.<br />
<br />
==== Usage ====<br />
<br />
Law 2 is the most interesting, it sais that we can '''apply a lens backwards''' with <hask>extend'</hask>. Backward lens application can introduce '''dependent local state'''.<br />
<br />
Consider the following pure lens:<br />
<br />
<haskell><br />
maybeLens :: Lens (Bool, a) (Maybe a)<br />
maybeLens<br />
= lens (\(b, a) -> if b then Just a else Nothing)<br />
(\x (_, a) -> maybe (False, a) (\a' -> (True, a')) x)<br />
</haskell><br />
<br />
Suppose that we have a reference <hask>r :: Lens S (Maybe Int)</hask>. Consider the following operation:<br />
<br />
<hask>extend' r maybeLens (False, 0)</hask><br />
<br />
This operations returns <hask>q :: Lens S (Bool, Int)</hask>. If we connect <hask>fstLens . q</hask> to a checkbox and <hask>sndLens . q</hask> to an integer entry field, we get the expected behaviour as described in the motivation.<br />
<br />
<hask>extend'</hask> introduces a dependent local state because <hask>q</hask> is automatically updated if <hask>r</hask> changes (and vice-versa).<br />
<br />
Backward lens application can solve long-standing problems with application of lenses, but that is another story to tell.<br />
<br />
==== References API ====<br />
<br />
Let <hask>S</hask> be an extensible state as specified above.<br />
Let <hask>s</hask> = <hask>S</hask> in the definition of references.<br />
<br />
* <hask>C :: (* -> *) -> * -> *</hask> ~ <hask>StateT S</hask>, the '''reference creating monad''', is the state monad transformer over <hask>S</hask>.<br />
<br />
The equality constraint is not exposed in the API.<br />
The following functions are exposed:<br />
<br />
* Dependent new reference creation<br />
<br />
<haskell><br />
extRef :: Monad m => Ref b -> Lens a b -> a -> C m (Ref a)<br />
extRef r k a0 = mapStateT (return . runIdentity) $ extend' r k a0<br />
</haskell><br />
<br />
* Lift reference modifying operations<br />
<br />
<haskell><br />
liftWrite :: Monad m => M a -> C m a<br />
liftWrite = mapStateT (return . runIdentity)<br />
</haskell><br />
<br />
* Derived <hask>MonadTrans</hask> instance of <hask>C</hask> to be able to lift operations in the <hask>m</hask> monad.<br />
<br />
Note that <hask>newRef</hask> can be defined in terms of <hask>extRef</hask> so <hask>extRef</hask> is more expressive than <hask>newRef</hask>:<br />
<br />
<haskell><br />
newRef :: Monad m => a -> C m (Ref a)<br />
newRef = extRef unitRef (lens (const ()) (const id))<br />
</haskell><br />
<br />
<br />
==== Implementation ====<br />
<br />
We prove constructively, by giving a reference implementation, that <hask>S</hask> exists. With this we also prove that <hask>S</hask> defined in the previous section exists because <hask>extend</hask> can be defined in terms of <hask>extend'</hask> (easy exercise: give the definition).<br />
<br />
Overview:<br />
<br />
The idea behind the implementation is that <hask>S</hask> not only stores a gradually extending state with type <hask>(a'', (a', (a, ...))</hask> but also a chain of lenses with type <hask>Lens (a'', (a', (a, ...))) (a', (a, ...))</hask>, <hask>Lens (a', (a, ...)) (a, ...)</hask>, <hask>Lens (a, ...) ...</hask>, <hask>...</hask>.<br />
<br />
When a new reference is created, both the state and the lens-chain are extended. The dependency between the newly created state part and the old state parts can be encoded into the new lens in the lens-chain.<br />
<br />
When a previously created reference (i.e. a lens) is accessed with a state after several extensions, a proper prefix of the lens-chain makes possible to convert the program state such that it fits the previously created reference.<br />
<br />
<br />
Reference implementation:<br />
<br />
Definition of <hask>S</hask>:<br />
<br />
<haskell><br />
type S = [Part]<br />
</haskell><br />
<br />
<haskell><br />
data Part = forall a . Part (S -> a -> a) a<br />
</haskell><br />
<br />
Note that instead of lenses, just set functions are stored, a simplification in the implementation.<br />
<br />
Definition of <hask>empty</hask>:<br />
<br />
<haskell><br />
empty :: S<br />
empty = []<br />
</haskell><br />
<br />
Auxiliary defintions:<br />
<br />
<haskell><br />
app :: S -> Part -> Part<br />
app s (Part f a) = Part f (f s a)<br />
</haskell><br />
<br />
<haskell><br />
snoc :: Part -> S -> S<br />
x `snoc` xs = xs ++ [x]<br />
</haskell><br />
<br />
Definition of <hask>extend'</hask>:<br />
<br />
<haskell><br />
extend' :: Lens S b -> Lens a b -> a -> State S (Lens S a)<br />
extend' r1 r2 a0 = state f where<br />
<br />
r21 = setL r1 . getL r2<br />
r12 = setL r2 . getL r1<br />
<br />
f x0 = (lens get set, Part r12 (r12 x0 a0) `snoc` x0)<br />
where<br />
n = length x0<br />
<br />
get = (\(Part _ a) -> unsafeCoerce a) . (!! n)<br />
<br />
set a x = foldl (\s -> (`snoc` s) . app s)<br />
(Part r12 a `snoc` r21 a (take n x))<br />
(drop (n+1) x)<br />
</haskell><br />
<br />
There are two sublte points in the implementation: the usage of <hask>unsafeCoerce</hask> and <hask>(!!)</hask>.<br />
<br />
If the values of <hask>S</hask> are used linearly, <hask>(!!)</hask> never fails and types will match at runtime so the use of <hask>unsafeCoerce</hask> is safe.<br />
<br />
== Effects ==<br />
<br />
TODO</div>Heisenbughttps://wiki.haskell.org/index.php?title=Embedded_domain_specific_language&diff=54553Embedded domain specific language2012-10-25T11:27:56Z<p>Heisenbug: observable sharing in graphs</p>
<hr />
<div>'''Embedded Domain Specific Language''' means that you embed a [http://en.wikipedia.org/wiki/Domain_specific_language Domain specific language] in a language like Haskell.<br />
E.g. using the [http://cryp.to/funcmp/ Functional MetaPost library] you can write Haskell expressions, which are then translated to MetaPost, MetaPost is run on the generated code and the result of MetaPost can be post-processed in Haskell.<br />
<br />
<br />
== Degree of embedding ==<br />
<br />
There are two major degrees of embedding:<br />
<br />
* Shallow embedding: All Haskell operations immediately translate to the target language. E.g. the Haskell expression <hask>a+b</hask> is translated to a <hask>String</hask> like <hask>"a + b"</hask> containing that target language expression.<br />
* Deep embedding: Haskell operations only build an interim Haskell data structure that reflects the expression tree. E.g. the Haskell expression <hask>a+b</hask> is translated to the Haskell data structure <hask>Add (Var "a") (Var "b")</hask>. This structure allows transformations like optimizations before translating to the target language.<br />
<br />
<br />
== Discussion of common problems ==<br />
<br />
[[Sharing]] and [http://en.wikipedia.org/wiki/Recursion recursion] are common problems when implementing DSLs.<br />
Often some kind of [[observable sharing]] is requested<br />
that requires a deep embedding.<br />
<br />
* Oleg in Haskell-Cafe about [http://www.haskell.org/pipermail/haskell-cafe/2008-February/039639.html Designing DSL with explicit sharing (was: I love purity, but it's killing me)]<br />
* Koen Classen: [http://www.cs.chalmers.se/~koen/pubs/entry-asian99-lava.html Observable Sharing for Functional Circuit Description]<br />
* Andy Gill: [http://www.ittc.ku.edu/~andygill/paper.php?label=DSLExtract09 Type-Safe Observable Sharing]<br />
* Tom Lokhorst [http://tom.lokhorst.eu/2010/02/awesomeprelude-presentation-video AwesomePrelude presentation (video)]<br />
* Leandro Lisboa Penz [http://lpenz.github.com/articles/hedsl-sharedexpenses/ Haskell eDSL Tutorial - Shared expenses]<br />
* Bruno Oliveira and William Cook: [http://www.cs.utexas.edu/~wcook/Drafts/2012/graphs.pdf Functional Programming with Structured Graphs]<br />
<br />
== Examples of Domain Specific Languages ==<br />
<br />
* [http://hackage.haskell.org/package/funcmp Functional MetaPost] is a Haskell frontend to the MetaPost language by John Hobby. Users write their graphics as Haskell programs, which then emit MetaPost code that can be compiled into encapsulated PostScript files and smoothly included into e.g. LaTeX. <br />
<br />
* [http://hackage.haskell.org/package/orc orc]: Orchestration-style coordination EDSL<br />
<br />
* [http://hackage.haskell.org/package/diagrams-cairo The diagrams-cairo package]. A full-featured backend for rendering diagrams using the cairo rendering engine. To get started, see Diagrams.Backend.Cairo.CmdLine.<br />
<br />
* [http://hackage.haskell.org/package/Workflow Workflow]: library for transparent execution of interruptible computations<br />
<br />
* [http://www.yesodweb.com/book/templates#file253-synopsis Hamlet, Julius, Cassius and Lucius] are languages embedded in the [http://www.yesodweb.com/ Yesod framework]<br />
<br />
== More to read/view ==<br />
<br />
* [http://skillsmatter.com/podcast/scala/haskell-for-embedded-domain-specific-languages Haskell for embedded domain-specific languages] (podcast)<br />
* [[Research papers/Domain specific languages]]<br />
* [http://donsbot.wordpress.com/2007/03/10/practical-haskell-shell-scripting-with-error-handling-and-privilege-separation/ Practical Haskell: shell scripting with error handling and privilege separation] (blog article)<br />
<br />
<br />
<br />
[[Category:Glossary]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=45325Template Haskell2012-04-19T18:17:08Z<p>Heisenbug: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/ . It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html The user manual section on Template Haskell]<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html#th-quasiquotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/template-haskell-2.5.0.0/Language-Haskell-TH.html The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 [formerly /bz/thdoc.htm]]<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj [formerly /bz/th3.htm]]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples are given in [http://hackage.haskell.org/package/haskell-src-meta haskell-src-meta].<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
[[Category:Language extensions]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=45324Template Haskell2012-04-19T18:09:59Z<p>Heisenbug: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/ . It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html The user manual section on Template Haskell]<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html#th-quasiquotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/template-haskell-2.5.0.0/Language-Haskell-TH.html The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 [formerly /bz/thdoc.htm]]<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj [formerly /bz/th3.htm]]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elemnts from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples are given in [http://hackage.haskell.org/package/haskell-src-meta haskell-src-meta].<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
[[Category:Language extensions]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Applicative_functor&diff=43632Applicative functor2011-12-17T05:53:46Z<p>Heisenbug: fixed link to UU</p>
<hr />
<div>[[Category:Glossary]]<br />
[[Category:Applicative Functor|*]]<br />
An applicative functor has more structure than a [[functor]] but less than a [[monad]]. See the Haddock docs for [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html Control.Applicative].<br />
<br />
== Example ==<br />
<br />
It has turned out that many applications do not require monad functionality but only those of applicative functors.<br />
Monads allow you to run actions depending on the outcomes of earlier actions.<br />
<haskell><br />
do text <- getLine<br />
if null text<br />
then putStrLn "You refuse to enter something?"<br />
else putStrLn ("You entered " ++ text)<br />
</haskell><br />
This is obviously necessary in some cases, but in other cases it is disadvantageous.<br />
<br />
Consider an extended IO monad which handles automated closing of allocated resources.<br />
This is possible with a monad.<br />
<haskell><br />
openDialog, openWindow :: String -> CleanIO ()<br />
<br />
liftToCleanup :: IO a -> CleanIO a<br />
<br />
runAndCleanup :: CleanIO a -> IO a<br />
<br />
runAndCleanup $<br />
do text <- liftToCleanup getLine<br />
if null text<br />
then openDialog "You refuse to enter something?"<br />
else openWindow ("You entered " ++ text)<br />
</haskell><br />
The (fictive) functions <hask>openDialog</hask> and <hask>openWindow</hask><br />
could not only open dialogs and windows but could also register some cleanup routine in the <hask>CleanIO</hask>.<br />
<hask> runAndCleanup </hask> would first run the opening actions and afterwards the required cleanup actions.<br />
I.e. if the dialog was opened, the dialog must be closed, but not the window.<br />
That is, the cleanup procedure depends on the outcomes of earlier actions.<br />
<br />
Now consider the slightly different task, where functions shall register ''initialization'' routines<br />
that shall be run before the actual action takes place.<br />
(See the original discussion started by Michael T. Richter in Haskell-Cafe:<br />
[http://www.haskell.org/pipermail/haskell-cafe/2007-June/027517.html Practical Haskell Question])<br />
This is impossible in the monadic framework.<br />
Consider the example above where the choice between <hask>openDialog</hask> and <hask>openWindow</hask><br />
depends on the outcome of <hask> getLine </hask>.<br />
You cannot run initialization code for either <hask>openDialog</hask> or <hask>openWindow</hask>,<br />
because you do not know which one will be called before executing <hask> getLine </hask>.<br />
If you eliminate this dependency, you end up in an applicative functor<br />
and there you can do the initialization trick.<br />
You could write<br />
<haskell><br />
initializeAndRun $<br />
liftA2<br />
(liftToInit getLine)<br />
(writeToWindow "You requested to open a window")<br />
</haskell><br />
where <hask> writeToWindow </hask> registers an initialization routine which opens the window.<br />
<br />
== Usage ==<br />
<br />
If you have the variables<br />
<haskell><br />
f :: a -> b -> c<br />
a :: f a<br />
b :: f b<br />
</haskell><br />
you can combine them in the following ways with the same result of type <hask>f c</hask>:<br />
<haskell><br />
pure f <*> a <*> b<br />
<br />
liftA2 f a b<br />
</haskell><br />
<br />
But how to cope with <hask>let</hask> and sharing in the presence of effects?<br />
Consider the non-functorial expression:<br />
<haskell><br />
x :: x<br />
g :: x -> y<br />
h :: y -> y -> z<br />
<br />
let y = g x<br />
in h y y<br />
</haskell><br />
Very simple.<br />
Now we like to generalize this to<br />
<haskell><br />
fx :: f x<br />
fg :: f (x -> y)<br />
fh :: f (y -> y -> z)<br />
</haskell><br />
However, we note that<br />
<haskell><br />
let fy = fg <*> fx<br />
in fh <*> fy <*> fy<br />
</haskell><br />
runs the effect of <hask>fy</hask> twice.<br />
E.g. if <hask>fy</hask> writes something to the terminal then <hask>fh <*> fy <*> fy</hask> writes twice.<br />
This could be intended, but how can we achieve,<br />
that the effect is run only once and the result is used twice?<br />
<br />
Actually, using the <hask>liftA</hask> commands we can pull results of applicative functors<br />
into a scope where we can talk exclusively about functor results and not about effects.<br />
Note that functor results can also be functions.<br />
This scope is simply a function, which contains the code that we used in the non-functorial setting.<br />
<haskell><br />
liftA3<br />
(\x g h -> let y = g x in h y y)<br />
fx fg fh<br />
</haskell><br />
The order of effects is entirely determined by the order of arguments to <hask>liftA3</hask>.<br />
<br />
== Some advantages of applicative functors ==<br />
<br />
* Code that uses only on the <hask>Applicative</hask> interface are more general than ones uses the <hask>Monad</hask> interface, because there are more applicative functors than monads. The <hask>ZipList</hask> is an applicative functor on lists, where <hask>liftA2</hask> is implemented by <hask>zipWith</hask>. It is a typical example of an applicative functor that is not a monad.<br />
* Programming with <hask>Applicative</hask> has a more applicative/functional feel. Especially for newbies, it may encourage functional style even when programming with effects. Monad programming with [[Do notation considered harmful|do notation]] encourages a more sequential & imperative style.<br />
<br />
== Applicative transfomers ==<br />
<br />
From the [[Monad Transformer Library]] we are used to have two flavours of every monad:<br />
A base monad like <hask>State</hask> and a transformer variant <hask>StateT</hask>.<br />
In the [http://hackage.haskell.org/package/transformers/ transformers] package we even have only monad transformers<br />
except the <hask>Identity</hask> monad.<br />
So where are applicative transformers?<br />
The answer is, that we do not need special transformers for applicative functors<br />
since they can be combined in a generic way.<br />
<haskell><br />
h :: f (g (a -> b))<br />
a :: f (g a)<br />
<br />
liftA2 (<*>) h a :: f (g b)<br />
</haskell><br />
That is <hask>liftA2 (<*>)</hask> is essentially the definition for <hask><*></hask><br />
for the composition of the functors <hask>f</hask> and <hask>g</hask>.<br />
This is implemented in the {{HackagePackage|id=TypeCompose}} library as type constructor <hask>O</hask> and in {{HackagePackage|id=transformers}} library in module <hask>Data.Functor.Compose</hask>.<br />
The first one needs a lot of type extensions, whereas the second one is entirely Haskell 98.<br />
<br />
It can be useful to use the applicative composition even when you have a monad transformer at hand.<br />
In the example above <hask>f</hask> might be <hask>Writer (Sum Int)</hask><br />
that is used for counting the number of involved applicative actions.<br />
Since in an applicative functor the number of run actions is independent from interim results,<br />
the writer can count the actions at compile time.<br />
<br />
== How to switch from monads ==<br />
<br />
* Start using <hask>liftM</hask>, <hask>liftM2</hask>, etc or <hask>ap</hask> where you can, in place of <hask>do</hask>/<hask>(>>=)</hask>. You will often encounter code like<br />
<haskell><br />
do x <- fx<br />
y <- fy<br />
return (g x y)<br />
</haskell><br />
:It can be rewritten to <hask>liftM2 g fx fy</hask>. In general, whenever the choice or construction of monadic actions does not depend on the outcomes of previous monadic actions, then it should be possible to rewrite everything with <hask>liftM</hask>.<br />
* When you notice you're ''only'' using those monad methods, then import <hask>Control.Applicative</hask> and replace<hask>return</hask> with <hask>pure</hask>, <hask>liftM</hask> with <hask>(<$>)</hask> (or <hask>fmap</hask> or <hask>liftA</hask>), <hask>liftM2</hask> with <hask>liftA2</hask>, etc, and <hask>ap</hask> with <hask>(<*>)</hask>. If your function signature was <hask>Monad m => ...</hask>, change to <hask>Applicative m => ...</hask> (and maybe rename <hask>m</hask> to <hask>f</hask> or whatever).<br />
<br />
<br />
== Alternative terms ==<br />
<br />
Applicative functors were introduced by several people under different names:<br />
* Ross Paterson called them [http://www.haskell.org/arrows/arrows/Control.Sequence.html Sequence]<br />
* Conor McBride called them [http://www.haskell.org/pipermail/haskell/2004-July/014315.html Idiom]<br />
* The same kind of structure is used in the [http://www.cs.uu.nl/wiki/Center/UtrechtParserCombinators UU Parsing-Combinators].<br />
<br />
<br />
== See also ==<br />
<br />
* [http://www.soi.city.ac.uk/~ross/papers/Applicative.html Applicative Programming with Effects]<br />
* The blog article [http://www.serpentine.com/blog/2008/02/06/the-basics-of-applicative-functors-put-to-practical-work/ The basics of applicative functors, put to practical work]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Simonpj/Talk:OutsideIn&diff=38537Simonpj/Talk:OutsideIn2011-02-08T17:45:56Z<p>Heisenbug: oops reduce brackets</p>
<hr />
<div>== Modular type inference with local assumptions: OutsideIn(X) ==<br />
<br />
This epic 73-page paper (JFP style) brings together our work on type inference for type functions, GADTS, and the like, in a single uniform framework. Version 2 is very substantially revised compared to the May 2010 version.<br />
<br />
* '''Modular type inference with local assumptions: OutsideIn(X): [http://research.microsoft.com/~simonpj/papers/constraints/jfp-outsidein.pdf Version 2 PDF]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/constraints/index.htm Related papers (constraints)]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Related papers (GADTs)]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/assoc-types/index.htm Related papers (type families)]'''<br />
<br />
<blockquote><br />
<p>'''Abstract'''. Advanced type system features, such as GADTs, type classes, and type families have have proven to be invaluable language extensions for ensuring data invariants and program correctness among others. Unfortunately, they pose a tough problem for type inference, because they introduce ''local'' type assumptions.<br />
</p><p><br />
In this article we present a novel constraint-based type inference approach for local type assumptions. Our system, called OutsideIn(X), is parameterised over the particular underlying constraint domain X, in the same way as HM(X). This stratification allows us to use a common metatheory and inference algorithm.<br />
</p><p><br />
Going beyond the general framework, we also give a particular constraint solver for X = type classes + GADTs + type families, a non-trivial challenge in its own right.<br />
</p></blockquote><br />
<br />
'''Please help us!'''. This Wiki page is a discussion page for the paper. If you are kind enough to read this paper, please help us by jotting down any thoughts it triggers off. Things to think about:<br />
* It is a long paper; where did you get lost? <br />
* What is unclear?<br />
* What is omitted that you'd like to see?<br />
* Is there anything we could leave out?<br />
<br />
You can identify your entries by preceding them with four tildes. Doing so adds your name, and the date. Thus:<br />
<br />
:[[User:Simonpj|Simonpj]] 08:42, 19 April 2007 (UTC) Note from Simon<br />
<br />
If you say who you are in this way, we'll be able to acknowledge your help in a revised version of the paper.<br />
<br />
[[User:Heisenbug|Heisenbug]] 17:42, 8 February 2011 (UTC) Note from Gabor Greif<br />
<br />
Just found this paper and had a quick look. You should probably compare your algorithm with ''Algorithm-P'' described in [http://sites.google.com/site/chklin/research Chuan-kai Lin's PhD thesis] where he claims to have developed a practical algorithm for GADT type inference. The work presumably obsoletes both references mentioned here to Lin's and Sheard's papers.<br />
<br />
------------------<br />
------------------<br />
'''Version 1 comments, now dealt with; thank you!'''<br />
<br />
:[[User:MeierSi|Simon Meier]] 15 May 2010: <br />
* Typo on Page 7: "having type Bool" should probably be "having type Int".<br />
* Typo on Page 18: "constraint siplifier"<br />
* Typo on Page 28: "topl-level"<br />
* Typo on Page 31: "But hang on! NoGen means ... in the beginning of Section 4.2 <text-missing-here>"<br />
* Typo on Page 53: Formula below "Simplification rules" is missing a space.<br />
* Typo on Page 59: "makes sens"<br />
<br />
[[User:Batterseapower|Batterseapower]] 14:24, 14 May 2010 (UTC) You say that local definitions such as "combine" and "swap" could harmlessly be defined at top level. However, there is a cost to doing so in that it pollutes the top-level namespace. Adding a facility for making definitions that are at the top level for the purposes of type checking but not for name resolution would fix this, at the cost of some ugliness.<br />
<br />
[[User:Rgreayer|Rgreayer]] 16:04, 14 May 2010 (UTC)<br />
* Revisiting Typo on Page 7: "This means that any expression of type F [Bool] can be considered an expression of type F Bool". But would that not mean the axiom is: F [a] ~ F a, rather than: F [a] ~ a?<br />
* Typo, Page 8 (middle): "An similar issue..."<br />
<br />
[[User:Saizan|Saizan]] 14:23, 16 May 2010 (UTC)<br />
* Figure 2: VarCon uses \nu in the conclusion and x in the premises, it seems they should both be \nu considering the textual description below, but then the definition of "Type environments" in Figure 1 also needs to have \nu rather than x.<br />
* typos in Section 9.1:<br />
** "f = case (Ex 3) of Ex -> False" should be "f = case (Ex 3) of Ex _ -> False".<br />
** "f :: Bool -> Bool" should be "f :: Bool".<br />
* Have you considered adding support for partial type signatures?<br />
<br />
[[User:niall|niall]] 15:07, 17 May 2010 (UTC) <br />
* Footnote on page 65 refers to an incorrect link (should perhaps be http://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/ ) although the journal paper does not seem linked from there. The Appendix with the algorithm is perhaps meant to refer to the appendix of "Simple unification-based type inference for GADTs"?<br />
<br />
[[User:Byorgey|Byorgey]] 09:10, 21 June 2010 (UTC)<br />
* p.8: should be a colon after "Here is an example"<br />
* p.10: end of section 2.2: "definition of g" should be "definition of test"<br />
* p.15: Indentation of "The judgement Q ; Gamma |- prog..." is too small<br />
* p.16: Grammar of Definition 3.1 needs fixing, for example, "An axiom scheme Q is consistent iff whenever ... *we have* (or, *it is also the case that*, etc.)<br />
* p.17: add comma after however in "For now, however algorithmic constraints..."<br />
* p.19: in Fig 7, should the Empty rule have a premise ftv(Q,Gamma) = empty?<br />
* p.21: I find it very confusing to use the notation t1 <= t2 for "t1 is more general than t2"; we are using a "less than" symbol for a concept involving the word "more"... Also, it took me a long time to grok details of the definition of "more general than", since it's contravariant in the constraints etc... it might be nice to add a paragraph giving a bit more explanation/intuition for this definition.<br />
* p.23, section 3.7: "Haskell type checker usually transform the program"<br />
* p.25: "...explain those modifications in Section 4 and Section 4.2" -- is the "Section 4" correct?<br />
* p.28: "...we abstract over the (Show a) constraint even though g is not polymorphic..." should be h instead of g?<br />
* p.29: "will hardly be delirious": delirious is a strange word choice, not sure what you are trying to convey.<br />
* p.31: "It is not enough to pick out equality constraints..." I find this section unclear. Perhaps a bit more detail would be helpful?<br />
* p.31: "But hang on! NoGen ..." incomplete sentence, and I do not know which f function you are referring to.<br />
* p.36: Period missing at the end of item 2.<br />
* p.37: In the first bullet point, missing comma after tau.<br />
* p.37: "This is obviously..." please drop "obviously", it is not obvious to me!<br />
* p.38: Fig. 13: There are two places where .tau_1 appear in LetA; what does this notation mean?<br />
* p.39: "Subsequently we may recursively solves"<br />
* p.40: last sentence of section 5.5, "being in domain of theta", add "the"<br />
* p.40, Lemma 5.1: "for all" instead of "forall"<br />
* p.45: Sentence "What this means is that ... typing rules" does not make sense. Also, foo is not a good example because in this *particular* case, the algorithm COULD detect the inconsistency.<br />
* p.46: first sentence, "The return type of foo..." is rather confusingly worded.<br />
* p.46: "between the programs typed the algorithm" add "by"<br />
* p.49, section 7.1: You should be more cafeul with the terms "type family", "type function", "function", "function-free"; I was initially confused and thought "function" and "function-free" was referring to function types like a -> b. For example at the top of page 49, "GHC enforces that type family instance declarations involve only functions applied to function-free types"... this confused me a lot at first, I was unsure why GHC would not allow arrow types in type family instance declarations!<br />
* p.49: "Given this syntax of constraints, Figure 17 gives..." should be Figure 18?<br />
* p.50: "for ever" should be "forever"<br />
* p.53, Fig. 20: In the definition of <_alpha, in the first case, what if tau = G vs? And how does a var compare to a non-var, and so on?<br />
* p.55, Fig. 21: Suppose we had an equality F x y z ~ G a b c, how would it be flattened? It seems we need to flatten away the application of G from the RHS but I do not see how the given rules accomplish, since they seem to only flatten things which are *arguments* to type functions on both sides.<br />
* p.56: "would get two new constraints: F beta ~ Int `union` G Int beta", missing a twiddle, should be G Int ~ beta<br />
* p.57, Fig 22: Why do we have both DDICTG and DDICTW? They seem identical.<br />
* p.57, Fig 22 (and Fig 23): given constraints F Int ~ a and a ~ Bool, should this be rewritten to F Int ~ Bool and a ~ Bool? Or does this not matter? There don't seem to be rules to accomplish this.<br />
* p.58: "...and a wanted constraint F Int a", missing a twiddle<br />
* p.59: the typesetting of |->s is strange, there needs to be more space after |->s since it currently overlaps with whatever comes after it<br />
* p.67: "NoQual is a no-option" -- probably better to say "is not an option"<br />
<br />
[[User:Longlivedeath|Longlivedeath]] 03:11, 15 July 2010 (UTC)<br />
<br />
* In the References section: replace "Fun with type '''fnnctions'''" to "Fun with type functions"<br />
<br />
[[User:Jobo|Jobo]] 12:07, 20 July 2010 (UTC)<br />
I just took a quick look at the references section:<br />
* There are some referenses to a Mr Jones, Simon Peyton.<br />
* References in the paper read ''etal.'' or ''et al'', shold be ''et al.'' (two words, ending in a dot).<br />
* Some references have the form "Sulzman et al. (Sulzmann et al. 2006); consider using \citet.</div>Heisenbughttps://wiki.haskell.org/index.php?title=Simonpj/Talk:OutsideIn&diff=38536Simonpj/Talk:OutsideIn2011-02-08T17:42:40Z<p>Heisenbug: suggest Lin's thesis</p>
<hr />
<div>== Modular type inference with local assumptions: OutsideIn(X) ==<br />
<br />
This epic 73-page paper (JFP style) brings together our work on type inference for type functions, GADTS, and the like, in a single uniform framework. Version 2 is very substantially revised compared to the May 2010 version.<br />
<br />
* '''Modular type inference with local assumptions: OutsideIn(X): [http://research.microsoft.com/~simonpj/papers/constraints/jfp-outsidein.pdf Version 2 PDF]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/constraints/index.htm Related papers (constraints)]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Related papers (GADTs)]'''<br />
* '''[http://research.microsoft.com/~simonpj/papers/assoc-types/index.htm Related papers (type families)]'''<br />
<br />
<blockquote><br />
<p>'''Abstract'''. Advanced type system features, such as GADTs, type classes, and type families have have proven to be invaluable language extensions for ensuring data invariants and program correctness among others. Unfortunately, they pose a tough problem for type inference, because they introduce ''local'' type assumptions.<br />
</p><p><br />
In this article we present a novel constraint-based type inference approach for local type assumptions. Our system, called OutsideIn(X), is parameterised over the particular underlying constraint domain X, in the same way as HM(X). This stratification allows us to use a common metatheory and inference algorithm.<br />
</p><p><br />
Going beyond the general framework, we also give a particular constraint solver for X = type classes + GADTs + type families, a non-trivial challenge in its own right.<br />
</p></blockquote><br />
<br />
'''Please help us!'''. This Wiki page is a discussion page for the paper. If you are kind enough to read this paper, please help us by jotting down any thoughts it triggers off. Things to think about:<br />
* It is a long paper; where did you get lost? <br />
* What is unclear?<br />
* What is omitted that you'd like to see?<br />
* Is there anything we could leave out?<br />
<br />
You can identify your entries by preceding them with four tildes. Doing so adds your name, and the date. Thus:<br />
<br />
:[[User:Simonpj|Simonpj]] 08:42, 19 April 2007 (UTC) Note from Simon<br />
<br />
If you say who you are in this way, we'll be able to acknowledge your help in a revised version of the paper.<br />
<br />
[[User:Heisenbug|Heisenbug]] 17:42, 8 February 2011 (UTC) Note from Gabor Greif<br />
<br />
Just found this paper and had a quick look. You should probably compare your algorithm with ''Algorithm-P'' described in [[http://sites.google.com/site/chklin/research Chuan-kai Lin's PhD thesis]] where he claims to have developed a practical algorithm for GADT type inference. The work presumably obsoletes both references mentioned here to Lin's and Sheard's papers.<br />
<br />
------------------<br />
------------------<br />
'''Version 1 comments, now dealt with; thank you!'''<br />
<br />
:[[User:MeierSi|Simon Meier]] 15 May 2010: <br />
* Typo on Page 7: "having type Bool" should probably be "having type Int".<br />
* Typo on Page 18: "constraint siplifier"<br />
* Typo on Page 28: "topl-level"<br />
* Typo on Page 31: "But hang on! NoGen means ... in the beginning of Section 4.2 <text-missing-here>"<br />
* Typo on Page 53: Formula below "Simplification rules" is missing a space.<br />
* Typo on Page 59: "makes sens"<br />
<br />
[[User:Batterseapower|Batterseapower]] 14:24, 14 May 2010 (UTC) You say that local definitions such as "combine" and "swap" could harmlessly be defined at top level. However, there is a cost to doing so in that it pollutes the top-level namespace. Adding a facility for making definitions that are at the top level for the purposes of type checking but not for name resolution would fix this, at the cost of some ugliness.<br />
<br />
[[User:Rgreayer|Rgreayer]] 16:04, 14 May 2010 (UTC)<br />
* Revisiting Typo on Page 7: "This means that any expression of type F [Bool] can be considered an expression of type F Bool". But would that not mean the axiom is: F [a] ~ F a, rather than: F [a] ~ a?<br />
* Typo, Page 8 (middle): "An similar issue..."<br />
<br />
[[User:Saizan|Saizan]] 14:23, 16 May 2010 (UTC)<br />
* Figure 2: VarCon uses \nu in the conclusion and x in the premises, it seems they should both be \nu considering the textual description below, but then the definition of "Type environments" in Figure 1 also needs to have \nu rather than x.<br />
* typos in Section 9.1:<br />
** "f = case (Ex 3) of Ex -> False" should be "f = case (Ex 3) of Ex _ -> False".<br />
** "f :: Bool -> Bool" should be "f :: Bool".<br />
* Have you considered adding support for partial type signatures?<br />
<br />
[[User:niall|niall]] 15:07, 17 May 2010 (UTC) <br />
* Footnote on page 65 refers to an incorrect link (should perhaps be http://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/ ) although the journal paper does not seem linked from there. The Appendix with the algorithm is perhaps meant to refer to the appendix of "Simple unification-based type inference for GADTs"?<br />
<br />
[[User:Byorgey|Byorgey]] 09:10, 21 June 2010 (UTC)<br />
* p.8: should be a colon after "Here is an example"<br />
* p.10: end of section 2.2: "definition of g" should be "definition of test"<br />
* p.15: Indentation of "The judgement Q ; Gamma |- prog..." is too small<br />
* p.16: Grammar of Definition 3.1 needs fixing, for example, "An axiom scheme Q is consistent iff whenever ... *we have* (or, *it is also the case that*, etc.)<br />
* p.17: add comma after however in "For now, however algorithmic constraints..."<br />
* p.19: in Fig 7, should the Empty rule have a premise ftv(Q,Gamma) = empty?<br />
* p.21: I find it very confusing to use the notation t1 <= t2 for "t1 is more general than t2"; we are using a "less than" symbol for a concept involving the word "more"... Also, it took me a long time to grok details of the definition of "more general than", since it's contravariant in the constraints etc... it might be nice to add a paragraph giving a bit more explanation/intuition for this definition.<br />
* p.23, section 3.7: "Haskell type checker usually transform the program"<br />
* p.25: "...explain those modifications in Section 4 and Section 4.2" -- is the "Section 4" correct?<br />
* p.28: "...we abstract over the (Show a) constraint even though g is not polymorphic..." should be h instead of g?<br />
* p.29: "will hardly be delirious": delirious is a strange word choice, not sure what you are trying to convey.<br />
* p.31: "It is not enough to pick out equality constraints..." I find this section unclear. Perhaps a bit more detail would be helpful?<br />
* p.31: "But hang on! NoGen ..." incomplete sentence, and I do not know which f function you are referring to.<br />
* p.36: Period missing at the end of item 2.<br />
* p.37: In the first bullet point, missing comma after tau.<br />
* p.37: "This is obviously..." please drop "obviously", it is not obvious to me!<br />
* p.38: Fig. 13: There are two places where .tau_1 appear in LetA; what does this notation mean?<br />
* p.39: "Subsequently we may recursively solves"<br />
* p.40: last sentence of section 5.5, "being in domain of theta", add "the"<br />
* p.40, Lemma 5.1: "for all" instead of "forall"<br />
* p.45: Sentence "What this means is that ... typing rules" does not make sense. Also, foo is not a good example because in this *particular* case, the algorithm COULD detect the inconsistency.<br />
* p.46: first sentence, "The return type of foo..." is rather confusingly worded.<br />
* p.46: "between the programs typed the algorithm" add "by"<br />
* p.49, section 7.1: You should be more cafeul with the terms "type family", "type function", "function", "function-free"; I was initially confused and thought "function" and "function-free" was referring to function types like a -> b. For example at the top of page 49, "GHC enforces that type family instance declarations involve only functions applied to function-free types"... this confused me a lot at first, I was unsure why GHC would not allow arrow types in type family instance declarations!<br />
* p.49: "Given this syntax of constraints, Figure 17 gives..." should be Figure 18?<br />
* p.50: "for ever" should be "forever"<br />
* p.53, Fig. 20: In the definition of <_alpha, in the first case, what if tau = G vs? And how does a var compare to a non-var, and so on?<br />
* p.55, Fig. 21: Suppose we had an equality F x y z ~ G a b c, how would it be flattened? It seems we need to flatten away the application of G from the RHS but I do not see how the given rules accomplish, since they seem to only flatten things which are *arguments* to type functions on both sides.<br />
* p.56: "would get two new constraints: F beta ~ Int `union` G Int beta", missing a twiddle, should be G Int ~ beta<br />
* p.57, Fig 22: Why do we have both DDICTG and DDICTW? They seem identical.<br />
* p.57, Fig 22 (and Fig 23): given constraints F Int ~ a and a ~ Bool, should this be rewritten to F Int ~ Bool and a ~ Bool? Or does this not matter? There don't seem to be rules to accomplish this.<br />
* p.58: "...and a wanted constraint F Int a", missing a twiddle<br />
* p.59: the typesetting of |->s is strange, there needs to be more space after |->s since it currently overlaps with whatever comes after it<br />
* p.67: "NoQual is a no-option" -- probably better to say "is not an option"<br />
<br />
[[User:Longlivedeath|Longlivedeath]] 03:11, 15 July 2010 (UTC)<br />
<br />
* In the References section: replace "Fun with type '''fnnctions'''" to "Fun with type functions"<br />
<br />
[[User:Jobo|Jobo]] 12:07, 20 July 2010 (UTC)<br />
I just took a quick look at the references section:<br />
* There are some referenses to a Mr Jones, Simon Peyton.<br />
* References in the paper read ''etal.'' or ''et al'', shold be ''et al.'' (two words, ending in a dot).<br />
* Some references have the form "Sulzman et al. (Sulzmann et al. 2006); consider using \citet.</div>Heisenbughttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=34007GHC/Type families2010-03-10T21:31:43Z<p>Heisenbug: typos</p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
<br />
== What are type families? ==<br />
<br />
Indexed type families, or type families for short, are type constructors that represent ''sets of types.'' Set members are denoted by supplying the type family constructor with type parameters, which are called ''type indices''. The difference between vanilla parametrised type constructors and family constructors is much like between parametrically polymorphic functions and (ad-hoc polymorphic) methods of type classes. Parametric polymorphic functions behave the same at all type instances, whereas class methods can change their behaviour in dependence on the class type parameters. Similarly, vanilla type constructors imply the same data representation for all type instances, but family constructors can have varying representation types for varying type indices.<br />
<br />
A tutorial paper that gives a number of examples of programming with type families is "[[Simonpj/Talk:FunWithTypeFuns|Fun with type functions]]" (2009).<br />
<br />
The rest of this page gives a more precise description of type families. Indexed type families come in two flavours: ''data families'' and ''type synonym families''. They are the indexed family variants of algebraic data types and type synonyms, respectively. The instances of data families can be data types and newtypes.<br />
<br />
== Type families in GHC ==<br />
<br />
Indexed type families are a new GHC extension to facilitate type-level programming. Type families are a generalisation of [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types] and [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html associated type synonyms], and are described in a [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html recent ICFP paper]. They essentially provide type-indexed data types and named functions on types, which are useful for generic programming and highly parameterised library interfaces as well as interfaces with enhanced static information, much like dependent types. They might also be regarded as an alternative to functional dependencies, but provide a more functional style of type-level programming than the relational style of functional dependencies.<br />
<br />
== What do I need to use type families? ==<br />
<br />
The first stable release of GHC that properly supports type families is 6.10.1. (An early partial implementation was part of the 6.8 release, but its use is deprecated.) Please [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&group=priority&type=bug&order=id&desc=1 report bugs] via the GHC bug tracker, ideally accompanied by a small example program that demonstrates the problem. Use the [mailto:glasgow-haskell-users@haskell.org GHC mailing list] for questions or for a discussion of this language extension and its description on this wiki page.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#data-family-declarations ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.IntMap</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.IntMap.IntMap v)<br />
empty = GMapInt Data.IntMap.empty<br />
lookup k (GMapInt m) = Data.IntMap.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.IntMap.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before, any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundamental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Next, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right b) v (GMapEither gm1 gm2) = GMapEither gm1 (insert b v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and querying a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Detailed definition of data families ==<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> keyword. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indices. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. In other words: '''the named type parameters of the data declaration must be a permutation of a subset of the class variables'''. <br />
<br />
Example is admissible:<br />
<haskell><br />
class C a b c where { data T c a :: * } -- OK<br />
class C a b c where { data T a a :: * } -- Bad: repeated variable<br />
class D a where { data T a x :: * } -- Bad: x is not a class variable<br />
class D a where { data T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed in type parameters, and type synonyms are allowed as long as they are fully applied and expand to a type that is itself admissible - exactly as this is required for occurrences of type synonyms in class instance parameters. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsense :: T a -> Int<br />
nonsense A = 1 -- WRONG: These two equations together...<br />
nonsense B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indices corresponding to class parameters must be identical to the type given in the instance head; here this is the first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Scoping of class parameters ====<br />
<br />
In the case of multi-parameter type classes, the visibility of class parameters in the right-hand side of associated family instances depends ''solely'' on the parameters of the data family. As an example, consider the simple class declaration<br />
<haskell><br />
class C a b where<br />
data T a<br />
</haskell><br />
Only one of the two class parameters is a parameter to the data family. Hence, the following instance declaration is invalid:<br />
<haskell><br />
instance C [c] d where<br />
data T [c] = MkT (c, d) -- WRONG!! 'd' is not in scope<br />
</haskell><br />
Here, the right-hand side of the data instance mentions the type variable <hask>d</hask> that does not occur in its left-hand side. We cannot admit such data instances as they would compromise type safety.<br />
<br />
==== Type class instances of family instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implicitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This is for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapEither</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== An associated type synonym example ==<br />
<br />
Type synonym families are an alternative to functional dependencies, which makes functional dependency examples well suited to introduce type synonym families. In fact, type families are a more functional way to express the same as functional dependencies (despite the name!), as they replace the relational notation of functional dependencies by an expression-oriented notation; i.e., functions on types are really represented by functions and not relations.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from Mark Jones' seminal paper on functional dependencies:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
Instead of the multi-parameter type class, we use a single parameter class, and the parameter <hask>e</hask><br />
turned into an associated type synonym <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Instances change correspondingly. An instance of the two-parameter class<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
becomes an instance of a single-parameter class, where the dependent type parameter turns into an associated type instance declaration:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1, Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
== Detailed definition of type synonym families ==<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Parameters can also be given explicit kind signatures if needed. We call the number of parameters in a type family declaration, the family's arity, and all applications of a type family must be fully saturated w.r.t. to that arity. This requirement is unlike ordinary type synonyms and it implies that the kind of a type family is not sufficient to determine a family's arity, and hence in general, also insufficient to determine whether a type family application is well formed. As an example, consider the following declaration:<br />
<haskell><br />
type family F a b :: * -> * -- F's arity is 2, <br />
-- although its overall kind is * -> * -> * -> *<br />
</haskell><br />
Given this declaration the following are examples of well-formed and malformed types:<br />
<haskell><br />
F Char [Int] -- OK! Kind: * -> *<br />
F Char [Int] Bool -- OK! Kind: *<br />
F IO Bool -- WRONG: kind mismatch in the first argument<br />
F Bool -- WRONG: unsaturated application<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
Exactly as in the case of an associated data declaration, '''the named type parameters must be a permutation of a subset of the class parameters'''. Examples<br />
<haskell><br />
class C a b c where { type T c a :: * } -- OK<br />
class D a where { type T a x :: * } -- No: x is not a class parameter<br />
class D a where { type T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed, and type synonyms are allowed as long as they are fully applied and expand to a type that is admissible - these are the exact same requirements as for data instances. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
A type family instance declaration must satisfy the following rules:<br />
* An appropriate family declaration is in scope - just like class instances require the class declaration to be visible. <br />
* The instance declaration conforms to the kind determined by its family declaration<br />
* The number of type parameters in an instance declaration matches the number of type parameters in the family declaration.<br />
* The right-hand side of a type instance must be a monotype (i.e., it may not include foralls) and after the expansion of all saturated vanilla type synonyms, no synonyms, except family synonyms may remain.<br />
<br />
Here are some examples of admissible and illegal type instances:<br />
<haskell><br />
type family F a :: *<br />
type instance F [Int] = Int -- OK!<br />
type instance F String = Char -- OK!<br />
type instance F (F a) = a -- WRONG: type parameter mentions a type family<br />
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter<br />
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type<br />
<br />
type family G a b :: * -> *<br />
type instance G Int = (,) -- WRONG: must be two type parameters<br />
type instance G Int Char Float = Double -- WRONG: must be two type parameters<br />
</haskell><br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a type family used in a single program may only overlap if the right-hand sides of the overlapping instances coincide for the overlapping types. More formally, two instance declarations overlap if there is a substitution that makes the left-hand sides of the instances syntactically the same. Whenever that is the case, the right-hand sides of the instances must also be syntactically equal under the same substitution. This condition is independent of whether the type family is associated or not, and it is not only a matter of consistency, but one of type safety.<br />
<br />
Here are two examples to illustrate the condition under which overlap is permitted.<br />
<haskell><br />
type instance F (a, Int) = [a]<br />
type instance F (Int, b) = [b] -- overlap permitted<br />
<br />
type instance G (a, Int) = [a]<br />
type instance G (Char, a) = [a] -- ILLEGAL overlap, as [Char] /= [Int]<br />
</haskell><br />
<br />
==== Decidability ====<br />
<br />
In order to guarantee that type inference in the presence of type families is decidable, we need to place a number of additional restrictions on the formation of type instance declarations (c.f., Definition 5 (Relaxed Conditions) of [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking with Open Type Functions]). Instance declarations have the general form<br />
<haskell><br />
type instance F t1 .. tn = t<br />
</haskell><br />
where we require that for every type family application <hask>(G s1 .. sm)</hask> in <hask>t</hask>, <br />
# <hask>s1 .. sm</hask> do not contain any type family constructors,<br />
# the total number of symbols (data type constructors and type variables) in <hask>s1 .. sm</hask> is strictly smaller than in <hask>t1 .. tn</hask>, and<br />
# for every type variable <hask>a</hask>, <hask>a</hask> occurs in <hask>s1 .. sm</hask> at most as often as in <hask>t1 .. tn</hask>.<br />
These restrictions are easily verified and ensure termination of type inference. However, they are not sufficient to guarantee completeness of type inference in the presence of, so called, ''loopy equalities'', such as <hask>a ~ [F a]</hask>, where a recursive occurrence of a type variable is underneath a family application and data constructor application - see the above mentioned paper for details. <br />
<br />
If the option <tt>-XUndecidableInstances</tt> is passed to the compiler, the above restrictions are not enforced and it is on the programmer to ensure termination of the normalisation of type families during type inference.<br />
<br />
=== Equality constraints ===<br />
<br />
Type context can include equality constraints of the form <hask>t1 ~ t2</hask>, which denote that the types <hask>t1</hask> and <hask>t2</hask> need to be the same. In the presence of type families, whether two types are equal cannot generally be decided locally. Hence, the contexts of function signatures may include equality constraints, as in the following example:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
</haskell><br />
where we require that the element type of <hask>c1</hask> and <hask>c2</hask> are the same. In general, the types <hask>t1</hask> and <hask>t2</hask> of an equality constraint may be arbitrary monotypes; i.e., they may not contain any quantifiers, independent of whether higher-rank types are otherwise enabled.<br />
<br />
Equality constraints can also appear in class and instance contexts. The former enable a simple translation of programs using functional dependencies into programs using family synonyms instead. The general idea is to rewrite a class declaration of the form<br />
<haskell><br />
class C a b | a -> b<br />
</haskell><br />
to<br />
<haskell><br />
class (F a ~ b) => C a b where<br />
type F a<br />
</haskell><br />
That is, we represent every functional dependency (FD) <hask>a1 .. an -> b</hask> by an FD type family <hask>F a1 .. an</hask> and a superclass context equality <hask>F a1 .. an ~ b</hask>, essentially giving a name to the functional dependency. In class instances, we define the type instances of FD families in accordance with the class head. Method signatures are not affected by that process.<br />
<br />
NB: Equalities in superclass contexts are not fully implemented in the GHC 6.10 branch.<br />
<br />
== Frequently asked questions ==<br />
<br />
=== Injectivity, type inference, and ambiguity ===<br />
<br />
A common problem is this<br />
<haskell><br />
type family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x<br />
</haskell><br />
The compiler complains about the definition of <tt>g</tt> saying<br />
<haskell><br />
Couldn't match expected type `F Int' against inferred type `F a1'<br />
</haskell><br />
In type-checking <tt>g</tt>'s right hand side GHC discovers (by instantiating <tt>f</tt>'s type with a fresh type variable) that it has type <tt>F a1 -> F a1</tt> for some as-yet-unknown type <tt>a1</tt>. Now it tries to make the inferred type match <tt>g</tt>'s type signature. Well, you say, just make <tt>a1</tt> equal to <tt>Int</tt> and you are done. True, but what if there were these instances<br />
<haskell><br />
type instance F Int = Bool<br />
type instance F Char = Bool<br />
</haskell><br />
Then making <tt>a1</tt> equal to <tt>Char</tt> would ''also'' make the two types equal. Because there is more than one choice, the program is rejected.<br />
<br />
Or, to put it another way, knowing that <tt>F t1</tt>=<tt>F t2</tt> does ''not'' imply that <tt>t1</tt> = <tt>t2</tt>.<br />
The difficulty is that the type function <tt>F</tt> need not be ''injective''; it can map two distinct types to the same type. For an injective type constructor like <tt>Maybe</tt>, if we know that <tt>Maybe t1</tt> = <tt>Maybe t2</tt>, then we know that <tt>t1</tt> = <tt>t2</tt>. But not so for non-injective type functions.<br />
<br />
The problem starts with <tt>f</tt>. Its type is ''ambiguous''; even if I know the argument and result types for <tt>f</tt>, I cannot use that to find the type at which <tt>a</tt> should be instantiated. (So arguably, <tt>f</tt> should be rejected as having an ambiguous type, and probably will be in future.) The situation is well known in type classes: <br />
<haskell><br />
bad :: (Read a, Show a) => String -> String<br />
bad x = show (read x)<br />
</haskell><br />
At a call of <tt>bad</tt> one cannot tell at what type <tt>a</tt> should be instantiated.<br />
<br />
The only solution is to avoid ambiguous types. In the type signature of a function, <br />
* Ensure that every type variable occurs in the part after the "<tt>=></tt>"<br />
* Ensure that every type variable appears at least once outside a type function call. <br />
<br />
Even then ambiguity is possible. For example:<br />
<haskell><br />
f :: F a -> [a] <br />
f = undefined<br />
<br />
g :: F b -> Int<br />
g x = length (f x)<br />
</haskell><br />
Although <tt>f</tt>'s type is unambiguous, its result type is swallowed up by <tt>length</tt>, which now makes <tt>g</tt>'s type ambiguous.<br />
<br />
== References ==<br />
<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html Associated Types with Class.] Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In ''Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)'', pages 1-13, ACM Press, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms.] Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In ''Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 241-253, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SCPD07.html System F with Type Equality Coercions.] Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. In ''Proceedings of The Third ACM SIGPLAN Workshop on Types in Language Design and Implementation'', ACM Press, 2007.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking With Open Type Functions.] Tom Schrijvers, Simon Peyton-Jones, Manuel M. T. Chakravarty, Martin Sulzmann. In ''Proceedings of The 13th ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 51-62, 2008.<br />
<br />
[[Category:Type-level programming]]<br />
[[Category:Language extension]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Research_papers/Type_systems&diff=33838Research papers/Type systems2010-02-25T16:44:21Z<p>Heisenbug: add pointwise paper</p>
<hr />
<div>__TOC__<br />
<br />
==Haskell semantics==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/static-semantics.dvi.gz A static semantics for Haskell]<br />
:SL Peyton Jones and PL Wadler, (draft), Department of Computing Science, University of Glasgow, 1992. (Cited by 20)<br />
<br />
;[http://haskell.org/onlinereport/dynamic-semantics.dvi.gz A Dynamic Semantics for Haskell] <br />
:Kevin Hammond and Cordelia Hall, (draft), University of Glasgow, 1992, 23 pages.<br />
<br />
;[http://citeseer.ist.psu.edu/424440.html Typing Haskell in Haskell] <br />
:Mark P. Jones, In Proceedings of the 1999 Haskell Workshop, Paris, France, October 1999. Published in Technical Report UU-CS-1999-28, Department of Computer Science, University of Utrecht. (Cited by 66)<br />
<br />
;[http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne/haskell_libs/hsparser.html HParser]<br />
:A parser for Haskell written purely in Haskell (using the Happy parser generator).<br />
<br />
;[http://www.cse.ogi.edu/~hallgren/Talks/LHiH/ A Lexer for Haskell in Haskell]<br />
:Thomas Hallgren, PacSoft Oregon Graduate Institute, 14 January, 2002<br />
<br />
;[http://citeseer.ist.psu.edu/launchbury93natural.html A Natural Semantics for Lazy Evaluation]<br />
:John Launchbury, Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, 144--154, 1993.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/papers/11.ps A Space Semantics for Core Haskell]<br />
:Adam Bakewell. Proc. 2000 Haskell Workshop. September 2001.<br />
<br />
==Pure type systems==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/henk.ps.gz Henk: a typed intermediate language]<br />
:SL Peyton Jones and E Meijer, Proceedings of the Types in Compilation Workshop, Amsterdam, June 1997.<br />
<br />
;[http://www.cs.uu.nl/~johanj/MSc/jwroorda/ Pure Type Systems for Functional Programming]<br />
:Jan-Willem Roorda, Masters Thesis, University of Utrecht, INF/SCR-00-13, available online, 2000<br />
<br />
==Dependent Types==<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/ydtm.pdf Why Dependent Types Matter]<br />
:Thorsten Altenkirch and Conor McBride and James McKinna, Manuscript, available online, April, 2005. (Cited by 7)<br />
<br />
;[http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html Simply Easy! An Implementation of a Dependently Typed Lambda Calculus]<br />
:Andres Löh, Conor McBride and Wouter Swierstra, 2007.<br />
<br />
==Unboxed values==<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/unboxed-values.ps.Z Unboxed values as first class citizens]<br />
:SL Peyton Jones and J Launchbury, Functional Programming Languages and Computer Architecture (FPCA'91), Boston, LNCS 523, Springer Verlag, Sept 1991, pp636-666. (Cited by 105)<br />
<br />
==Modules==<br />
<br />
;[http://www.cse.ogi.edu/~diatchki/papers/modules98.pdf A Formal Specification of the Haskell 98 Module System]<br />
:Iavor S. Diatchki, Mark P. Jones, and Thomas Hallgren. Proceedings of the 2002 ACM SIGPLAN workshop on Haskell. Pittsburgh, Pennsylvania. 17 - 28 2002 ISBN 1-58113-605-6 (Cited by 12)<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/first-class-modules/index.htm First class modules for Haskell]<br />
:Mark Shields and Simon Peyton Jones; FOOL'02.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/Nicklisch-modules.ps.gz An exploration of modular programs]<br />
:Electronic proceedings of the 1996 Glasgow Functional Programming Workshop, J Nicklisch and SL Peyton Jones, Ullapool, July 1996.<br />
<br />
==Exceptions==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf An Extensible Dynamically-Typed Hierarchy of Exceptions]<br />
:Simon Marlow. Haskell '06: Proceedings of the 2006 ACM SIGPLAN workshop on Haskell, Portland, Oregon, ACM Press, September 2006<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn-sem.htm Imprecise Exceptions, Co-Inductively]<br />
:Andy Moran, Soeren Lassen, and Simon Peyton Jones. HOOTS'99.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm A semantics for imprecise exceptions]<br />
:Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Language Design and Implementation (PLDI'99), Atlanta.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm Asynchronous exceptions in Haskell]<br />
:Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy, PLDI'01.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/except6.ps.gz Handling Exceptions in Haskell]<br />
:A. Reid, Research Report YALEU/DCS/RR-1175, Yale University, August, 1998<br />
<br />
==Lexically scoped type variables==<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/papers/scoped%2Dtyvars/ Lexically scoped type variables]<br />
:Simon Peyton Jones and Mark Shields. 2004.<br />
<br />
==Records==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
:Mark Jones and Simon Peyton Jones, Haskell Workshop 1999.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/scopedlabels.pdf Extensible records with scoped labels]<br />
:Daan Leijen. The 2005 Symposium on Trends in Functional Programming (TFP'05), Tallin, Estonia, September 2005.<br />
<br />
;[http://www.cs.uu.nl/~daan/download/papers/fclabels.pdf First-class labels for extensible rows]<br />
:Daan Leijen. Technical Report UU-CS-2004-51, Departement of Computer Science, Universiteit Utrecht, 2004.<br />
<br />
;[http://www.reid-consulting-uk.ltd.uk/alastair/publications/h-wkshop95a/index.html Haskell Records]<br />
:J. Peterson, A. Reid, Proceedings of the Haskell Workshop, La Jolla, June 1995. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/96-3.ps.gz A Polymorphic Type System for Extensible Records and Variants]<br />
:Benedict R. Gaster and Mark P. Jones. Department of Computer Science, University of Nottingham. Technical report NOTTCS-TR-96-3. November 1996.<br />
<br />
==Meta programming==<br />
<br />
;[http://research.microsoft.com/copyright/accept.asp?path=/users/simonpj/papers/dyntyping.ps.gz&pub=ACM Dynamic typing as staged type inference]<br />
:MB Shields, T Sheard, and SL Peyton Jones, POPL98.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/meta-haskell/index.htm Template meta-programming for Haskell]<br />
:Tim Sheard and Simon Peyton Jones, Proceedings of the Haskell Workshop, Pittsburgh, 2002<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCK04.html Optimising Embedded DSLs using Template Haskell]<br />
:Sean Seefried, Manuel M. T. Chakravarty, and Gabriele Keller. In Gabor Karsai and Eelco Visser, editors, Third International Conference on Generative Programming and Component Engineering (GPCE'04), LNCS 3286, Springer-Verlag, pages 186-205, 2004. [An earlier draft was presented at the IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, 2003.<br />
<br />
;[http://www.haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps Unrolling and Simplifying Expressions with Template Haskell]<br />
:Ian Lynagh, May 2003.<br />
<br />
;[http://www.haskell.org/th/papers/hlpp.ps Automatic skeletons in Template Haskell]<br />
:Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. Proceedings of 2003 Workshop on High Level Parallel Programming, Paris, France<br />
<br />
;[http://www.haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps Typing Template Haskell: Soft Types]<br />
:Ian Lynagh, August 2004.<br />
<br />
==Dynamic typing==<br />
<br />
;[http://www.cs.uu.nl/groups/ST/stbib/swierstra-by-year/BaSw02.bib Typing dynamic typing]<br />
:A. I. Baars and S. D. Swierstra. In S. Peyton Jones, editor, Proceedings of the seventh ACM SIGPLAN international conference on Functional programming, pages 157--166. ACM Press, 2002<br />
<br />
==Parametricity==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps.gz Theorems for free!]<br />
:Philip Wadler. 4'th International Conference on Functional Programming and Computer Architecture, London, September 1989.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/pointed.html Parametricity and Unboxing with Unpointed Types]<br />
:John Launchbury and Ross Paterson, European Symposium on Programming, LNCS, vol. 1058, pp. 204-218, Springer, Linkping, Sweden, 1996.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/seqFinal.pdf The Impact of seq on Free Theorems-Based Program Transformations]<br />
:Patricia Johann and Janis Voigtländer, Fundamenta Informaticae, vol. 69(1-2), pp. 63-102, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/TCS.pdf Selective strictness and parametricity in structural operational semantics, inequationally]<br />
:Janis Voigtländer and Patricia Johann, Theoretical Computer Science, vol. 388(1-3), pp. 290-318, 2007.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/pepm09-voigtlaender.pdf Proving Correctness via Free Theorems: The Case of the destroy/build-Rule]<br />
:Janis Voigtländer. Workshop on Partial Evaluation and Program Manipulation (PEPM'08), Proceedings, ACM Press, 2008.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/iandc.pdf A family of syntactic logical relations for the semantics of Haskell-like languages]<br />
:Patricia Johann and Janis Voigtländer, Information and Computation, vol. 207(2), pp. 341-368, 2009.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/tlca09.pdf Parametricity for Haskell with Imprecise Error Semantics]<br />
:Florian Stenger and Janis Voigtländer. International Conference on Typed Lambda Calculi and Applications (TLCA'09), Proceedings, Springer-Verlag, 2009.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/icfp09.pdf Free Theorems Involving Type Constructor Classes]<br />
:Janis Voigtländer. International Conference on Functional Programming (ICFP'09), Proceedings, ACM Press, 2009.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/atps09.pdf Taming Selective Strictness]<br />
:Daniel Seidel and Janis Voigtländer. Arbeitstagung Programmiersprachen (ATPS'09), Proceedings, GI, 2009.<br />
<br />
;[http://www.iai.uni-bonn.de/~jv/FTForCurry.pdf Free Theorems for Functional Logic Programs]<br />
:Jan Christiansen, Daniel Seidel, and Janis Voigtländer. Programming Languages meets Program Verification (PLPV'10), Proceedings, ACM Press, 2010.<br />
<br />
;[http://www.iai.uni-bonn.de/~jv/paper.pdf Automatically Generating Counterexamples to Naive Free Theorems]<br />
:Daniel Seidel and Janis Voigtländer. Functional and Logic Programming (FLOPS'10), Proceedings, Springer-Verlag, 2010.<br />
<br />
<br />
==Type classes==<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz How to make ad-hoc polymorphism less ad hoc]<br />
:Philip Wadler and Stephen Blott. 16'th Symposium on Principles of Programming Languages, ACM Press, Austin, Texas, January 1989.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/classhask.ps.gz Type classes in Haskell, CV Hall, K Hammond, SL Peyton Jones, and PL Wadler]<br />
:European Symposium On Programming, LNCS 788, Springer Verlag, pp. 241-256, April 1994. (Cited by 131)<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/pldi93.html Implementing Type Classes]<br />
:John Peterson and Mark P. Jones, In Proceedings of ACM SIGPLAN Symposium on Programming Language Design and Implementation, ACM SIGPLAN, June 1993. (Cited by 40)<br />
<br />
;[http://www.cs.chalmers.se/pub/cs-reports/papers/overload-fpca-93.ps.Z Implementing Haskell overloading]<br />
:Lennart Augustsson, 1993. FPCA. 65-73<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/springschool.html Functional Programming with Overloading and Higher-Order Polymorphism]<br />
:Mark P. Jones, First International Spring School on Advanced Functional Programming Techniques, Baastad, Sweden, Springer-Verlag Lecture Notes in Computer Science 925, May 1995.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/type-class-design-space Type classes: exploring the design space]<br />
:Simon Peyton Jones, Mark Jones, Erik Meijer, Haskell Workshop 1997.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca93.html A system of constructor classes: overloading and implicit higher-order polymorphism]<br />
:Mark P. Jones, In FPCA '93: Conference on Functional Programming Languages and Computer Architecture, Copenhagen, Denmark, June 1993.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/overload2/overload2.ps.gz A second look at overloading]<br />
:Martin Odersky, Philip Wadler, Martin Wehr. 7'th International Conference on Functional Programming and Computer Architecture, ACM Press, San Diego, California, June 1995.<br />
<br />
;[http://citeseer.ist.psu.edu/laufer94combining.html Combining Type Classes and Existential Types]<br />
:Konstantin Laufer, Proceedings of the Latin American Informatic Conference (PANEL), 1994<br />
<br />
;[http://citeseer.ist.psu.edu/aufer95type.html Type Classes with Existential Types]<br />
:Konstantin Laufer, Journal of Functional Programming, 1996, May<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/DHCK06.html Modular Type Classes]<br />
:Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty and Gabriele Keller, 2006<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/4.pdf Named instances for Haskell type classes]<br />
:W Kahl, J Scheffczyk - Proc. Haskell Workshop, 2001 (Cited by 12)<br />
<br />
===Deriving type classes===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/derive.htm Derivable Type classes] <br />
:Ralf Hinze and Simon Peyton Jones, Haskell Workshop 2000.<br />
<br />
;[http://www.cis.upenn.edu/~sweirich/RepLib/ RepLib: A Library for Derivable Type Classes]<br />
:Stephanie Weirich 2006<br />
<br />
===Applications of type classes===<br />
<br />
;[http://okmij.org/ftp/Haskell/number-parameterized-types.html Number-parameterized types]<br />
:Oleg Kiselyov, The Monad.Reader. IssueFive. Oct 2nd, 2005<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/typecase.pdf TypeCase: a design pattern for type-indexed functions]<br />
:Bruno C. d. S. Oliveira, Jeremy Gibbons. Proceedings of the 2005 ACM SIGPLAN workshop on Haskell. Tallinn, Estonia. 98 - 109, 2005 ISBN:1-59593-071-X<br />
<br />
;[http://okmij.org/ftp/Haskell/types.html#Prepose Functional pearl: implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan, Proceedings of the 2004 ACM SIGPLAN workshop on Haskell, Snowbird, Utah, USA, 2004 ISBN 1-58113-850-4<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/extract-typeclassproofs.pdf Extracting Programs from Type Class Proofs]<br />
:Martin Sulzmann, 2006<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/coind-type-class-proofs.ps Co-induction and Type Improvement in Type Class Proofs]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey. 2005<br />
<br />
;[http://www.cs.nott.ac.uk/~ctm/faking.ps.gz Faking It (Simulating Dependent Types in Haskell)]<br />
:Conor McBride, Journal of Functional Programming, 12(4&5):375-392, July 2002<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/aophaskell.ps.gz Aspect-Oriented Programming with Type Classes]<br />
:Martin Sulzmann and Meng Wang, 2006.<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/mpc08.pdf Asymptotic Improvement of Computations over Free Monads]<br />
:Janis Voigtländer. Mathematics of Program Construction (MPC'08), Proceedings, LNCS 5133:388-403, Springer-Verlag, 2008.<br />
<br />
<br />
==Undecidable instances==<br />
<br />
;[http://www.haskell.org/ghc/docs/6.4.2/html/users_guide/type-extensions.html#undecidable-instances Undecidable instances]<br />
:GHC User's Guide.<br />
<br />
==Multi-parameter type classes==<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/ghc-mptc-inf.ps Principal Type Inference for GHC-Style Multi-Parameter Type Classes]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey. In APLAS'06.<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/mptc-inf-old.pdf Type Inference for Multi-Parameter Type Classes]<br />
:Martin Sulzmann and Peter J. Stuckey. 2005<br />
<br />
;[http://ostrich.lcs.mit.edu/cgi-bin/pickbib?jfp::DugganO2002 Type-checking multi-parameter type classes]<br />
:Dominic Duggan and John Ophel, Journal of Functional Programming, 12(2):133-158, March 2002<br />
<br />
==Functional dependencies==<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fundeps.html Type Classes with Functional Dependencies]<br />
:Mark P. Jones, In Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782.<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/fd-chr/index.htm Sound and Decidable Type Inference for Functional Dependencies]<br />
:Gregory J. Duck, Simon Peyton Jones, Peter J. Stuckey, and Martin Sulzmann, European Symposium on Programming 2004 (ESOP'04).<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/jfp-fds-revised.pdf Understanding Functional Dependencies via Constraint Handling Rules]<br />
:Martin Sulzmann, Gregory J. Duck, Simon Peyton-Jones and Peter J. Stuckey.j To appear in Journal of Functional Programming. 2006<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/afds.ps Associated Functional Dependencies]<br />
:Martin Sulzmann and Edmund Soon Lee Lam. 2005<br />
<br />
==Constraint Handling Rules==<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/aplas06-invited.pdf Type Processing by Constraint Reasoning]<br />
:Peter J. Stuckey, Martin Sulzmann and Jeremy Wazny, In APLAS'06.<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/chr-stm.ps A Concurrent Constraint Handling Rules Implementation in Haskell with Software Transactional Memory]<br />
:Edmund S.L. Lam and Martin Sulzmann<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/chr06-observable.ps Observable Confluence for Constraint Handling Rules]<br />
:Gregory J. Duck, Peter J. Stuckey and Martin Sulzmann<br />
<br />
==Generalised Algebraic Data Types (GADTs)==<br />
<br />
;[http://research.microsoft.com/~simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs]<br />
:Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. Submitted to PLDI 2005<br />
<br />
;[http://www.cis.upenn.edu/~geoffw/research/papers/MS-CIS-05-26.pdf Wobbly types: type inference for generalised algebraic data types]<br />
:S Peyton Jones, G. Washburn, and S. Weirich. 2004.<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F]<br />
:Martin Sulzmann and Meng Wang. 2005<br />
<br />
;[http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types]<br />
:François Pottier and Yann Régis-Gianas, 2006<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/gadt-short.ps Type Inference for GADTs via Herbrand Constraint Abduction]<br />
:Martin Sulzmann, Tom Schrijvers and Peter J. Stuckey, 2006 <br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/publications/tr-eadt.ps.gz A Framework for Extended Algebraic Data Types]<br />
:Martin Sulzmann, Jeremy Wazny and Peter J. Stuckey, 2006<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/implication_constraints.pdf Complete and Decidable Type Inference for GADTs]<br />
:Tom Schrijvers, Simon Peyton-Jones, Martin Sulzmann and Dimitrios Vytiniotis, 2009.<br />
<br />
;[http://web.cecs.pdx.edu/~cklin/pointwise/pointwise-tldi10.pdf Pointwise Generalized Algebraic Data Types]<br />
:Chuan-kai Lin and Tim Sheard, 2010.<br />
<br />
See also the [[GADT]] page.<br />
<br />
==Parametric Regular Data Types==<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/parametric-regular.ps Type Inference and Compilation for Parametric Regular Data Types]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu, 2006<br />
<br />
;[http://www.cs.mu.oz.au/~sulzmann/manuscript/haskell-xduce.ps The Marriage of Haskell and XDuce]<br />
:Martin Sulzmann and Kenny Zhuo Ming Lu<br />
<br />
==Type Families and Associated types==<br />
<br />
;[http://www.haskell.org/~simonmar/papers/assoc.pdf Associated types with class]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, Simon Marlow) POPL '05: Proceedings of the 32nd ACM SIGPLAN-SIGACT sysposium on Principles of programming languages, pages 1--13, Long Beach, California, USA, ACM Press, 2005<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms]<br />
:Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming, ACM Press, pages 241-253, 2005.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/diplom ML Modules and Haskell Type Classes: A Constructive Comparison]<br />
:Stefan Wehr Diplomarbeit. Albert-Ludwigs-Universitt Freiburg, Fakultt fr Angewandte Wissenschaften, Institut fr Informatik, November 2005. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/SCP06.html System F with Type Equality Coercions]<br />
:Martin Sulzmann, Manuel M. T. Chakravarty, and Simon Peyton Jones.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/type_functions.pdf Towards Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Martin Sulzmann, and Manuel Chakravarty. In Proceedings of IFL' 07, Freiburg, Germany, 2007.<br />
<br />
;[http://www.cs.kuleuven.be/~toms/Research/papers/draft_type_functions_2008.pdf Type Checking with Open Type Functions for Haskell]<br />
:Tom Schrijvers, Simon Peyton Jones, Manuel Chakravarty, and Martin Sulzmann. In Proceedings of ICFP' 08, Victoria, Canada, 2008.<br />
<br />
<br />
==Arbitrary-rank polymorphism==<br />
<br />
;[http://www.ubka.uni-karlsruhe.de/vvv/1996/informatik/81/81.pdf.gz Putting type annotations to work]<br />
:Martin Odersky and Konstantin Läufer. Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. St. Petersburg Beach, Florida, United States. 54 - 67 1996 ISBN 0-89791-769-3<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext%3Ffulltextid%3D445910 Practical type inference for arbitrary-rank types]<br />
:SP Jones, M Shields - Submitted to the Journal of Functional Programming, 2005<br />
<br />
==Phantom types==<br />
<br />
;[http://techreports.library.cornell.edu:8081/Dienst/UI/1.0/Display/cul.cis/TR2003-1901 First-class phantom types]<br />
:James Cheney and Ralf Hinze. Technical Report TR2003-1901, Cornell University, 2003.<br />
<br />
;[http://ttic.uchicago.edu/~fluet/research/phantom-subtyping/jfp06/jfp06.pdf Phantom Types and Subtyping]<br />
:Matthew Fluet and Riccardo Pucella. Submitted to the Journal of Functional Programming, 2006.<br />
<br />
==Implicit parameters==<br />
<br />
;[http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/implicit.ps Implicit Parameters: Dynamic Scoping with Static Types]<br />
:Jeffrey Lewis, Mark Shields, Erik Meijer and John Launchbury. POPL'00. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. J. Funct. Program. 14(5): 489-502 (2004) <br />
<br />
;[http://www.cs.uu.nl/pub/RUU/CS/techreps/CS-2004/2004-059.pdf Explicit Implicit Parameters]<br />
:A. Dijkstra and S. D. Swierstra. UU-CS 2004-059, 2004.<br />
<br />
==Object oriented Haskell==<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] <br />
:Mark Shields and Simon Peyton Jones; BABEL workshop '01.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/PC03.html Interfacing Haskell with Object-Oriented Languages]<br />
:Andr T. H. Pang and Manuel M. T. Chakravarty. In Greg Michaelson and Phil Trinder, editors, Implementation of Functional Languages: 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, LNCS 3145, Springer-Verlag, pages 20-36, 2004. <br />
<br />
;[http://citeseer.ist.psu.edu/118134.html Haskell++: An Object-Oriented Extension of Haskell]<br />
:Jan Sparud and John Hughes. Haskell Workshop 1995<br />
<br />
;[http://homepages.cwi.nl/~ralf/OOHaskell/ Haskell's overlooked object system]<br />
:Oleg Kiselyov and Ralf Lämmel, submitted for journal publication; online since 30 Sep. 2004;<br />
<br />
==Restricted Datatypes==<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Papers/restricted-datatypes.ps Restricted datatypes]<br />
:John Hughes. 1999 Haskell workshop<br />
<br />
==Patterns==<br />
<br />
;[http://www.cs.yale.edu/homes/tullsen/patterns.ps First Class Patterns]<br />
:Mark Tullsen. Practical Aspects of Declarative Languages, Second International Workshop, PADL 2000. volume 1753 of Lecture Notes in Computer Science. January 2000. <br />
<br />
===Pattern guards===<br />
<br />
;[http://research.microsoft.com/~simonpj/Papers/pat.htm Pattern Guards and Transformational Patterns]<br />
:Martin Erwig and Simon Peyton Jones; Haskell Workshop 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Haskell/guards.html A new view of guards]<br />
:Simon Peyton Jones, April 1997<br />
<br />
===Views===<br />
<br />
;[http://www.haskell.org/development/views.html Views: An Extension to Haskell Pattern Matching]<br />
:Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson and Phil Wadler.<br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps.gz Views: A way for pattern matching to cohabit with data abstraction]<br />
:POPL 14 (1987), 307-313.<br />
<br />
==Qualified types==<br />
<br />
;[http://haskell.readscheme.org/servlets/cite.ss?pattern=mpj-jones1994a Qualified Types: Theory and Practice]<br />
:Mark P. Jones. PhD. Thesis. Yale University. November 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/fpca95.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. FPCA '95: Conference on Functional Programming Languages and Computer Architecture. June 1995.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-1040.ps Simplifying and Improving Qualified Types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-1040. June 1994.<br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/RR-989.ps Coherence for qualified types]<br />
:Mark P. Jones. Yale University. Research Report YALEU/DCS/RR-989. September 1993. <br />
<br />
;[http://www.cse.ogi.edu/~mpj/pubs/rev-qual-types.ps A theory of qualified types]<br />
:Mark P. Jones. ESOP '92: European Symposium on Programming. Lecture Notes in Computer Science, 582. February 1992. (Cited by 68)<br />
<br />
==Polymorphic recursion==<br />
<br />
;[http://portal.acm.org/citation.cfm%3Fcoll%3DGUIDE%26dl%3DGUIDE%26id%3D169692 Type inference with polymorphic recursion]<br />
:F Henglein - ACM Transactions on Programming Languages and Systems (1993)<br />
<br />
;[http://www.jucs.org/jucs_9_8/practical_type_inference_for/paper.pdf Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell]<br />
:C Vasconcellos, L Figueiredo, C Camarao - Journal of Universal Computer Science, 2003<br />
<br />
;[http://www.dcc.ufmg.br/~camarao/ml0-impl.ps Type Inference for Polymorphic Recursive Definitions: a Specification in Haskell]<br />
:L Figueiredo, C Camarao<br />
<br />
[[Category:Research]]<br />
[[Category:Type-level programming]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=HacPDX&diff=30712HacPDX2009-10-10T06:54:35Z<p>Heisenbug: typo</p>
<hr />
<div>'''September 25-27 2009'''<br />
<br />
Portland, Oregon, USA<br />
<br />
== About ==<br />
HacPDX is an opportunity to join Portland Haskell hackers in building and improving Hackage libraries and tools. If you've never been, Hackathons are typically not only a good opportunity for experienced devs to work together but <br />
also a great way for newcomers to get involved in the community.<br />
<br />
== Communication Channels ==<br />
<br />
During the event, you can reach us at<br />
<br />
irc://irc.freenode.net/##hacpdx<br />
+1 503 725 2812<br />
thomas.dubuisson+hacpdx at gmail.com<br />
<br />
Also, check the [[/Projects|projects]] page as we update it to see what is happening.<br />
<br />
== Publicity ==<br />
<br />
* Calagator : http://calagator.org/events/1250457547<br />
<br />
== When ==<br />
Friday Sept 25 3:30PM to 6:00 PM<br />
Saturday Sept 26 10:00AM to 6:00 PM<br />
Sunday Sept 27 10:00AM to 6:00 PM<br />
<br />
We can work however late, but tentatively let's plan on eating and sleeping.<br />
<br />
The Friday times give an opportunity to meet and test your network connectivity, should you so desire. Afterwards we can head out to grab a pint! <br />
<br />
== Where ==<br />
We will be in room 86-01 (downstairs) of the [http://maps.google.com/maps/ms?ie=UTF8&hl=en&t=h&msa=0&msid=109280870257923598159.00047041b966a19099376&ll=45.506933,-122.682095&spn=0.022768,0.055661&z=15 fourth avenue building], which is part of Portland State University.<br />
<br />
As the building is locked during the weekends, I'll be letting attendees in via the Harrison Street entrance.<br />
<br />
== Equipment ==<br />
You should bring a laptop with wireless (802.11). The room has whiteboards and a projector for any discussions or should anyone wish to give a talk.<br />
<br />
== News ==<br />
* 11Aug09 - Announced HacPDX... only one week later than intended!<br />
<br />
== Registration ==<br />
Go to the [[/Registration|HacPDX Registration]] page and add your name as an attendee - the selected room can fit a population in the low-twenties well enough and we'll work to acquire the larger room if needed.<br />
<br />
Be sure to list any [[/Projects|projects]] in which you're interested!<br />
<br />
== Food ==<br />
Getting food might involve a little more of a walk (I'll do some research, feel free to add suggestions if you're a local), but there are many restaurants down town.<br />
<br />
[Tim says] nearby options that are open on weekends include but are not limited to:<br />
* Hot Lips Pizza, SW 6th and Hall (2 blocks away)<br />
* Taco Del Mar (next door)<br />
* Baan Thai, SW College and Broadway<br />
* Thanh Long, SW College and Broadway (Vietnamese)<br />
* Chipotle, SW College and Broadway<br />
* Cheerful Tortoise, SW College and Broadway (beer and grease)<br />
<br />
== Travel ==<br />
Buses 12, 44, and 17 all stop right outside the Fourth Avenue Building. The Yellow and Green Lines of the MAX stop a few blocks away. If you're biking from the east side just take Hawthorne bridge, a left on first, and a right on Harrison - the building is on the corner of Harrison and 4th. <br />
<br />
If you want to attend and are coming from outside of Portland feel free to ask for a hand.<br />
<br />
== Organizers ==<br />
<br />
* Thomas DuBuisson (irc: TomMD, e-mail: Thomas.DuBuisson+hacpdx@gmail.com)<br />
<br />
[[Category:Community]]<br />
[[Category:Events]]<br />
[[Category:Hackathon]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Tutorials&diff=23838Tutorials2008-11-02T23:03:20Z<p>Heisenbug: add attribution</p>
<hr />
<div>==Introductions to Haskell==<br />
<br />
These are the recommended places to start learning, short of buying a textbook.<br />
<br />
=== Best places to start ===<br />
<br />
;[http://darcs.haskell.org/yaht/yaht.pdf Yet Another Haskell Tutorial]<br />
:By Hal Daume III et al. A recommended tutorial for Haskell that is still under construction but covers already much ground. Also a classic text. Now available [http://en.wikibooks.org/wiki/Haskell/YAHT as a wikibook].<br />
<br />
;[http://en.wikibooks.org/wiki/Haskell Haskell Wikibook] <br />
:A communal effort by several authors to produce the definitive Haskell textbook. Its very much a work in progress at the moment, and contributions are welcome.<br />
<br />
;[http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/overview.html Write Yourself a Scheme in 48 Hours in Haskell]<br />
:A Haskell Tutorial, by Jonathan Tang. Most Haskell tutorials on the web seem to take a language-reference-manual approach to teaching. They show you the syntax of the language, a few language constructs, and then have you construct a few simple functions at the interactive prompt. The "hard stuff" of how to write a functioning, useful program is left to the end, or sometimes omitted entirely. This tutorial takes a different tack. You'll start off with command-line arguments and parsing, and progress to writing a fully-functional Scheme interpreter that implements a good-sized subset of R5RS Scheme. Along the way, you'll learn Haskell's I/O, mutable state, dynamic typing, error handling, and parsing features. By the time you finish, you should be fairly fluent in both Haskell and Scheme.<br />
<br />
;[http://learnyouahaskell.com Learn You a Haskell for Great Good!]<br />
: Nicely illustrated tutorial showing Haskell concepts while interacting in GHCi. Written and drawn by Miran Lipovača.<br />
<br />
=== More tutorials ===<br />
<br />
;[http://www.haskell.org/tutorial/ A Gentle Introduction to Haskell] :By Paul Hudak, John Peterson, and Joseph H. Fasel. The title is misleading. Some knowledge of another functional programming language is expected. The emphasis is on the type system and those features which are really new in Haskell (compared to other functional programming languages). A classic, but not for the faint of heart (it's not so gentle). Also available in [http://gorgonite.developpez.com/livres/traductions/haskell/gentle-haskell/ French] and [http://www.rsdn.ru/article/haskell/haskell_part1.xml Russian].<br />
<br />
;[[H-99: Ninety-Nine Haskell Problems]]<br />
:A collection of programming puzzles, with Haskell solutions. Solving these is a great way to get into Haskell programming.<br />
<br />
;[http://www.haskell.org/~pairwise/intro/intro.html Haskell Tutorial for C Programmers]<br />
:By Eric Etheridge. From the intro: "This tutorial assumes that the reader is familiar with C/C++, Python, Java, or Pascal. I am writing for you because it seems that no other tutorial was written to help students overcome the difficulty of moving from C/C++, Java, and the like to Haskell."<br />
<br />
;[http://www-106.ibm.com/developerworks/edu/os-dw-linuxhask-i.html Beginning Haskell] <br />
:From IBM developerWorks. This tutorial targets programmers of imperative languages wanting to learn about functional programming in the language Haskell. If you have programmed in languages such as C, Pascal, Fortran, C++, Java, Cobol, Ada, Perl, TCL, REXX, JavaScript, Visual Basic, or many others, you have been using an imperative paradigm. This tutorial provides a gentle introduction to the paradigm of functional programming, with specific illustrations in the Haskell 98 language. (Free registration required.)<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/teaching/Hskurs_toc.html Online Haskell Course] <br />
:By Ralf Hinze (in German).<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/tutorials.html Tutorial Papers in Functional Programming].<br />
:A collection of links to other Haskell tutorials, from John Hughes.<br />
<br />
;[http://www.cs.ou.edu/cs1323h/textbook/haskell.shtml Two Dozen Short Lessons in Haskell] <br />
:By Rex Page. A draft of a textbook on functional programming, available by ftp. It calls for active participation from readers by omitting material at certain points and asking the reader to attempt to fill in the missing information based on knowledge they have already acquired. The missing information is then supplied on the reverse side of the page. <br />
<br />
;[ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf Haskell-Tutorial] <br />
:By Damir Medak and Gerhard Navratil. The fundamentals of functional languages for beginners. <br />
<br />
;[http://video.s-inf.de/#FP.2005-SS-Giesl.(COt).HD_Videoaufzeichnung Video Lectures] <br />
:Lectures (in English) by Jürgen Giesl. About 30 hours in total, and great for learning Haskell. The lectures are 2005-SS-FP.V01 through 2005-SS-FP.V26. Videos 2005-SS-FP.U01 through 2005-SS-FP.U11 are exercise answer sessions, so you probably don't want those.<br />
<br />
;[http://www.cs.utoronto.ca/~trebla/fp/ Albert's Functional Programming Course] <br />
:A 15 lesson introduction to most aspects of Haskell.<br />
<br />
;[http://www.iceteks.com/articles.php/haskell/1 Introduction to Haskell]<br />
:By Chris Dutton, An "attempt to bring the ideas of functional programming to the masses here, and an experiment in finding ways to make it easy and interesting to follow".<br />
<br />
;[http://www.csc.depauw.edu/~bhoward/courses/0203Spring/csc122/haskintro/ An Introduction to Haskell]<br />
:A brief introduction, by Brian Howard.<br />
<br />
;[http://web.syntaxpolice.org/lectures/haskellTalk/slides/index.html Introduction to Haskell]<br />
:By Isaac Jones (2003).<br />
<br />
;[http://www.linuxjournal.com/article/9096 Translating Haskell into English]<br />
:By Shannon Behrens, a glimpse of the Zen of Haskell, without requiring that they already be Haskell converts.<br />
<br />
;[http://www.shlomifish.org/lecture/Perl/Haskell/slides/ Haskell for Perl Programmers]<br />
:Brief introduction to Haskell, with a view to what perl programmers are interested in<br />
<br />
;[http://lisperati.com/haskell/ How To Organize a Picnic on a Computer]<br />
:Fun introduction to Haskell, step by step building of a program to seat people at a planned picnic, based on their similarities using data from a survey and a map of the picnic location.<br />
<br />
;[http://cs.wwc.edu/KU/PR/Haskell.html Haskell Tutorial]<br />
<br />
;[http://www.lisperati.com/haskell/ Conrad Barski's Haskell tutorial .. with robots]<br />
<br />
;[[Media:Introduction.pdf|Frederick Ross's Haskell introduction]]<br />
<br />
== Motivation for using Haskell ==<br />
<br />
;[http://www.md.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters] <br />
:By [http://www.md.chalmers.se/~rjmh/ John Hughes], The Computer Journal, Vol. 32, No. 2, 1989, pp. 98 - 107. Also in: David A. Turner (ed.): Research Topics in Functional Programming, Addison-Wesley, 1990, pp. 17 - 42.<BR> Exposes the advantages of functional programming languages. Demonstrates how higher-order functions and lazy evaluation enable new forms of modularization of programs.<br />
<br />
;[[Why Haskell matters]] <br />
:Discussion of the advantages of using Haskell in particular. An excellent article.<br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1997/224/index.html Higher-order + Polymorphic = Reusable] <br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson]. Unpublished, May 1997.<BR> <STRONG>Abstract:</STRONG> This paper explores how certain ideas in object oriented languages have their correspondents in functional languages. In particular we look at the analogue of the iterators of the C++ standard template library. We also give an example of the use of constructor classes which feature in Haskell 1.3 and Gofer.<br />
<br />
;[http://www-128.ibm.com/developerworks/java/library/j-cb07186.html Explore functional programming with Haskell]<br />
:Introduction to the benefits of functional programming in Haskell by Bruce Tate.<br />
<br />
== Blog articles ==<br />
<br />
There are a large number of tutorials covering diverse Haskell topics<br />
published as blogs. Some of the best of these articles are collected<br />
here:<br />
<br />
;[[Blog articles]]<br />
<br />
==Practical Haskell==<br />
<br />
These tutorials examine using Haskell to writing complex real-world applications<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/Papers/marktoberdorf Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell]<br />
:Simon Peyton Jones. Presented at the 2000 Marktoberdorf Summer School. In "Engineering theories of software construction", ed Tony Hoare, Manfred Broy, Ralf Steinbruggen, IOS Press, ISBN 1-58603-1724, 2001, pp47-96. The standard reference for monadic IO in GHC/Haskell. <br><strong>Abstract:</strong>Functional programming may be beautiful, but to write real applications we must grapple with awkward real-world issues: input/output, robustness, concurrency, and interfacing to programs written in other languages.<br />
<br />
;[[Hitchhikers Guide to the Haskell]]<br />
: Tutorial for C/Java/OCaml/... programers by Dmitry Astapov. From the intro: "This text intends to introduce the reader to the practical aspects of Haskell from the very beginning (plans for the first chapters include: I/O, darcs, Parsec, QuickCheck, profiling and debugging, to mention a few)".<br />
<br />
;[http://haskell.org/haskellwiki/IO_inside Haskell I/O inside: Down the Rabbit's Hole]<br />
:By Bulat Ziganshin (2006), a comprehensive tutorial on using IO monad.<br />
<br />
;[http://web.archive.org/web/20060622030538/http://www.reid-consulting-uk.ltd.uk/docs/ffi.html A Guide to Haskell's Foreign Function Interface]<br />
:A guide to using the foreign function interface extension, using the rich set of functions in the Foreign libraries, design issues, and FFI preprocessors.<br />
<br />
;[http://blogs.nubgames.com/code/?p=22 Haskell IO for imperative programmers]<br />
:A short introduction to IO from the perspective of an imperative programmer.<br />
<br />
;[[A brief introduction to Haskell|A Brief Introduction to Haskell]]<br />
:A translation of the article, [http://www.cs.jhu.edu/~scott/pl/lectures/caml-intro.html Introduction to OCaml], to Haskell.<br />
<br />
;[[Roll your own IRC bot]]<br />
:This tutorial is designed as a practical guide to writing real world code in Haskell and hopes to intuitively motivate and introduce some of the advanced features of Haskell to the novice programmer, including monad transformers. Our goal is to write a concise, robust and elegant IRC bot in Haskell.<br />
<br />
;[http://haskell.org/gtk2hs/docs/tutorial/glade/ Glade Tutorial (GUI Programming)]<br />
:For the absolute beginner in both Glade and Gtk2Hs. Covers the basics of Glade and how to access a .glade file and widgets in Gtk2Hs. Estimated learning time: 2 hours.<br />
;[http://www.muitovar.com/glade/es-index.html Tutorial de Glade]<br />
:A Spanish translation of the Glade tutorial<br />
<br />
;[http://www.muitovar.com/index.xhtml#sec3 Gtk2Hs Tutorial]<br />
: An extensive Gtk2Hs programming guide, based on the GTK+2.0 tutorial by Tony Gale and Ian Main. This tutorial on GUI programming with Gtk2Hs has 22 chapters in 7 sections, plus an appendix on starting drawing with Cairo. A Spanish translation and source code of the examples are also available.<br />
<br />
;Applications of Functional Programming<br />
:Colin Runciman and David Wakeling (ed.), UCL Press, 1995, ISBN 1-85728-377-5 HB. From the cover:<blockquote>This book is unique in showcasing real, non-trivial applications of functional programming using the Haskell language. It presents state-of-the-art work from the FLARE project and will be an invaluable resource for advanced study, research and implementation.</blockquote><br />
<br />
;[[DealingWithBinaryData]] a guide to bytestrings, the various <tt>Get</tt> monads and the <tt>Put</tt> monad.<br />
<br />
===Testing===<br />
<br />
;[http://blog.moertel.com/articles/2006/10/31/introductory-haskell-solving-the-sorting-it-out-kata Small overview of QuickCheck]<br />
<br />
;[[Introduction to QuickCheck]]<br />
<br />
==Reference material==<br />
<br />
;[http://haskell.org/haskellwiki/Category:Tutorials A growing list of Haskell tutorials on a diverse range of topics]<br />
:Available on this wiki<br />
<br />
;[http://haskell.org/haskellwiki/Category:How_to "How to"-style tutorials and information]<br />
<br />
;[http://undergraduate.csse.uwa.edu.au/units/230.301/lectureNotes/tourofprelude.html A Tour of the Haskell Prelude (basic functions)] <br />
:By Bernie Pope and Arjan van IJzendoorn.<br />
<br />
;[http://cs.anu.edu.au/Student/comp1100/haskell/tourofsyntax.html Tour of the Haskell Syntax] <br />
:By Arjan van IJzendoorn.<br />
<br />
;[http://zvon.org/other/haskell/Outputglobal/index.html Haskell Reference] <br />
:By Miloslav Nic.<br />
<br />
;[http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions]<br />
:By Henk-Jan van Tuyl.<br />
<br />
;[http://www.cse.unsw.edu.au/~en1000/haskell/inbuilt.html Useful Haskell functions]<br />
:An explanation for beginners of many Haskell functions that are predefined in the Haskell Prelude.<br />
<br />
;[http://www.cs.chalmers.se/Cs/Grundutb/Kurser/d1pt/d1pta/ListDoc/ Haskell's Standard List Functions]<br />
:A tour of the standard Haskell functions, directed by what you want to achieve<br />
<br />
;[http://haskell.org/ghc/docs/latest/html/libraries/ Documentation for the standard libraries]<br />
:Complete documentation of the standard Haskell libraries.<br />
<br />
;[http://www.haskell.org/haskellwiki/Category:Idioms Haskell idioms]<br />
:A collection of articles describing some common Haskell idioms. Often quite advanced.<br />
<br />
;[http://www.haskell.org/haskellwiki/Blow_your_mind Useful idioms]<br />
:A collection of short, useful Haskell idioms.<br />
<br />
;[http://www.haskell.org/haskellwiki/Programming_guidelines Programming guidelines]<br />
:Some Haskell programming and style conventions.<br />
<br />
;[http://www.md.chalmers.se/~rjmh/Combinators/LightningTour/index.htm Lightning Tour of Haskell]<br />
:By John Hughes, as part of a Chalmers programming course<br />
<br />
;[http://www.cs.chalmers.se/~augustss/AFP/manuals/haskeller.dvi.gz The Little Haskeller] <br />
:By Cordelia Hall and John Hughes. 9. November 1993, 26 pages. An introduction using the Chalmers Haskell B interpreter (hbi). Beware that it relies very much on the user interface of hbi which is quite different for other Haskell systems, and the tutorials cover Haskell 1.2 , not Haskell 98.<br />
<br />
;[http://www.cs.uu.nl/people/jeroen/courses/fp-eng.pdf Functional Programming]<br />
:By Jeroen Fokker, 1995. (153 pages, 600 KB). Textbook for learning functional programming with Gofer (an older implementation of Haskell). Here without Chapters&nbsp;6 and&nbsp;7.<br />
<br />
== Comparisons to other languages ==<br />
<br />
Articles constrasting feature of Haskell with other languages.<br />
<br />
;[http://programming.reddit.com/goto?id=nq1k Haskell versus Scheme]<br />
:Mark C. Chu-Carroll, Haskell and Scheme: Which One and Why?<br />
<br />
;[http://wiki.python.org/moin/PythonVsHaskell Comparing Haskell and Python]<br />
:A short overview of similarities and differences between Haskell and Python.<br />
<br />
;[http://programming.reddit.com/goto?id=nwm2 Monads in OCaml]<br />
:Syntax extension for monads in OCaml<br />
<br />
;[http://www.shlomifish.org/lecture/Perl/Haskell/slides/ Haskell for Perl programmers]<br />
:Short intro for perlers<br />
<br />
;[[A_brief_introduction_to_Haskell|Introduction to Haskell]] versus [http://www.cs.jhu.edu/~scott/pl/lectures/caml-intro.html Introduction to OCaml].<br />
<br />
;[http://www.thaiopensource.com/relaxng/derivative.html An algorithm for RELAX NG validation]<br />
:by James Clark (of RELAX NG fame). Describes an algorithm for validating an XML document against a RELAX NG schema, uses Haskell to describe the algorithm. The algorithm in Haskell and Java is then [http://www.donhopkins.com/drupal/node/117 discussed here].<br />
<br />
;[http://mult.ifario.us/articles/2006/10/11/first-steps-with-haskell-for-web-applications Haskell + FastCGI versus Ruby on Rails]<br />
:A short blog entry documenting performance results with ruby on rails and Haskell with fastcgi<br />
<br />
;[http://haskell.org/papers/NSWC/jfp.ps Haskell vs. Ada vs. C++ vs. Awk vs. ..., An Experiment in Software Prototyping Productivity] (postscript)<br />
:Paul Hudak and Mark P. Jones, 16 pages.<blockquote>Description of the results of an experiment in which several conventional programming languages, together with the functional language Haskell, were used to prototype a Naval Surface Warfare Center requirement for Geometric Region Servers. The resulting programs and development metrics were reviewed by a committee chosen by the US Navy. The results indicate that the Haskell prototype took significantly less time to develop and was considerably more concise and easier to understand than the corresponding prototypes written in several different imperative languages, including Ada and C++. </blockquote> <br />
<br />
;[http://www.osl.iu.edu/publications/prints/2003/comparing_generic_programming03.pdf A Comparative Study of Language Support for Generic Programming] (pdf)<br />
:Ronald Garcia, Jaakko Jrvi, Andrew Lumsdaine, Jeremy G. Siek, and Jeremiah Willcock. In Proceedings of the 2003 ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA'03), October 2003.<blockquote>An interesting comparison of generic programming support across languages, including: Haskell, SML, C++, Java, C#. Haskell supports all constructs described in the paper -- the only language to do so. </blockquote><br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/realworld/index.html Functional Programming in the Real World]<br />
:A list of functional programs applied to real-world tasks. The main criterion for being real-world is that the program was written primarily to perform some task, not primarily to experiment with functional programming. Functional is used in the broad sense that includes both `pure' programs (no side effects) and `impure' (some use of side effects). Languages covered include CAML, Clean, Erlang, Haskell, Miranda, Scheme, SML, and others.<br />
<br />
;[http://www.defmacro.org/ramblings/lisp-in-haskell.html Lisp in Haskell]<br />
:Writing A Lisp Interpreter In Haskell, a tutorial<br />
<br />
== Teaching Haskell ==<br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1997/208/index.html Where do I begin? A problem solving approach to teaching functional programming]<br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson]. In Krzysztof Apt, Pieter Hartel, and Paul Klint, editors, First International Conference on Declarative Programming Languages in Education. Springer-Verlag, September 1997. <br> <STRONG>Abstract:</STRONG> This paper introduces a problem solving method for teaching functional programming, based on Polya's `How To Solve It', an introductory investigation of mathematical method. We first present the language independent version, and then show in particular how it applies to the development of programs in Haskell. The method is illustrated by a sequence of examples and a larger case study. <br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1995/214/index.html Functional programming through the curriculum]<br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson] and Steve Hill. In Pieter H. Hartel and Rinus Plasmeijer, editors, Functional Programming Languages in Education, LNCS 1022, pages 85-102. Springer-Verlag, December 1995. <br> <STRONG>Abstract:</STRONG> This paper discusses our experience in using a functional language in topics across the computer science curriculum. After examining the arguments for taking a functional approach, we look in detail at four case studies from different areas: programming language semantics, machine architectures, graphics and formal languages. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CK02a.html The Risks and Benefits of Teaching Purely Functional Programming in First Year]<br />
:By [http://www.cse.unsw.edu.au/~chak Manuel M. T. Chakravarty] and [http://www.cse.unsw.edu.au/~keller Gabriele Keller]. Journal of Functional Programming 14(1), pp 113-123, 2004. An earlier version of this paper was presented at Functional and Declarative Programming in Education (FDPE02). <br> <strong>Abstract</strong> We argue that teaching purely functional programming as such in freshman courses is detrimental to both the curriculum as well as to promoting the paradigm. Instead, we need to focus on the more general aims of teaching elementary techniques of programming and essential concepts of computing. We support this viewpoint with experience gained during several semesters of teaching large first-year classes (up to 600 students) in Haskell. These classes consisted of computer science students as well as students from other disciplines. We have systematically gathered student feedback by conducting surveys after each semester. This article contributes an approach to the use of modern functional languages in first year courses and, based on this, advocates the use of functional languages in this setting.<br />
<br />
<br />
==Using monads==<br />
<br />
See also the [[Monad]] HaskellWiki page.<br />
<br />
<br />
===Recommended tutorials===<br />
<br />
;[http://www.haskell.org/all_about_monads/html/index.html All About Monads] <br />
:By Jeff Newbern. This tutorial aims to explain the concept of a monad and its application to functional programming in a way that is easy to understand and useful to beginning and intermediate Haskell programmers. Familiarity with the Haskell language is assumed, but no prior experience with monads is required. <br />
<br />
;[[Monads as computation]]<br />
:A tutorial which gives a broad overview to motivate the use of monads as an abstraction in functional programming and describe their basic features. It makes an attempt at showing why they arise naturally from some basic premises about the design of a library.<br />
<br />
;[[Monads as containers]]<br />
:A tutorial describing monads from a rather different perspective: as an abstraction of container-types, rather than an abstraction of types of computation.<br />
<br />
;[http://uebb.cs.tu-berlin.de/~magr/pub/Transformers.en.html Monad Transformers Step by Step]<br />
:By Martin Grabm&uuml;ller. A small tutorial on using monad transformers. In contrast to others found on the web, it concentrates on using them, not on their implementation.<br />
<br />
===Parser===<br />
<br />
;[http://www.haskell.org/sitewiki/images/c/c6/ICMI45-paper-en.pdf The Parser monad and other monad (i.e. a monad with state and I/O string)]. <br />
:The parser monad is used to build modular, flexible, parsers. <br />
<br />
;[http://www.haskell.org/sitewiki/images/c/c6/ICMI45-paper-en.pdf How to build a monadic interpreter in one day] (pdf)<br />
:By Dan Popa. A small tutorial on how to build a language in one day, using the Parser Monad in the front end and a monad with state and I/O string in the back end. Read it if you are interested in learning: <br />
:# language construction and <br />
:# interpreter construction<br />
<br />
===More tutorials===<br />
<br />
;[http://stefan-klinger.de/files/monadGuide.pdf The Haskell Programmer's Guide to the IO Monad - Don't Panic.] <br />
:By Stefan Klinger. This report scratches the surface of category theory, an abstract branch of algebra, just deep enough to find the monad structure. It seems well written.<br />
<br />
;[http://www.prairienet.org/~dsb/monads.htm A (hopefully) painless introduction to monads] <br />
:By Dan Bensen. A straightforward beginner's guide with intuitive explanations and examples.<br />
<br />
;[http://www-users.mat.uni.torun.pl/~fly/materialy/fp/haskell-doc/Monads.html What the hell are Monads?] <br />
:By Noel Winstanley. A basic introduction to monads, monadic programming and IO. This introduction is presented by means of examples rather than theory, and assumes a little knowledge of Haskell. <br />
<br />
;[http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm Monads for the Working Haskell Programmer -- a short tutorial]<br />
:By Theodore Norvell. <br />
<br />
;[http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html You Could Have Invented Monads! (And Maybe You Already Have.)]<br />
:A short tutorial on monads, introduced from a pragmatic approach, with less category theory references <br />
<br />
;[http://www.cs.chalmers.se/~augustss/AFP/monads.html Systematic Design of Monads]<br />
:By John Hughes and Magnus Carlsson. Many useful monads can be designed in a systematic way, by successively adding facilities to a trivial monad. The capabilities that can be added in this way include state, exceptions, backtracking, and output. Here we give a brief description of the trivial monad, each kind of extension, and sketches of some interesting operations that each monad supports.<br />
<br />
;[[Meet Bob The Monadic Lover]]<br />
:By Andrea Rossato. A by-the-author-supposed-to-be funny and short introduction to Monads, with code but without any reference to category theory: what monads look like and what they are useful for, from the perspective of a ... lover. (There is also the slightly more serious [[The Monadic Way]] by the same author.)<br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2006-November/019190.html Monstrous Monads]<br />
:Andrew Pimlott's humourous introduction to monads, using the metaphor of "monsters".<br />
<br />
;Computational monads on Reddit, by [http://programming.reddit.com/info/ox6s/comments/coxiv tmoertel] and [http://programming.reddit.com/info/ox6s/comments/coxoh dons].<br />
<br />
;[http://www.loria.fr/~kow/monads/index.html Of monads and space suits]<br />
:By Eric Kow.<br />
<br />
;[[The Monadic Way]]<br />
<br />
;[http://www.alpheccar.org/fr/posts/show/60 Three kind of monads] : sequencing, side effects or containers<br />
<br />
;[[Simple monad examples]]<br />
<br />
;[http://en.wikipedia.org/wiki/Monads_in_functional_programming Article on monads on Wikipedia]<br />
<br />
;[[IO inside]] page<br />
:Explains why I/O in Haskell is implemented with a monad.<br />
<br />
;[http://haskell.org/haskellwiki/Blog_articles#Monads Blog articles]<br />
<br />
;[[Monad Transformers Explained]]<br />
<br />
;[http://www.muitovar.com/monad/moncow.xhtml The Greenhorn's Guide to becoming a Monad Cowboy]<br />
:Covers basics in a ''for dummies'' style. Estimated learning time 1-2 days.<br />
<br />
<br />
See also [[Research papers/Monads and arrows]]<br />
<br />
==Workshops on advanced functional programming==<br />
<br />
;[http://compilers.iecc.com/comparch/article/95-04-024 Advanced Functional Programming: 1st International Spring School on Advanced Functional Programming Techniques], Bastad, Sweden, May 24 - 30, 1995. Tutorial Text (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cse.ogi.edu/PacSoft/conf/summerschool96.html Advanced Functional Programming: 2nd International School], Olympia, Wa, Usa, August 26-30, 1996 Tutorial Text (Lecture Notes in Computer Science) <br />
<br />
;[http://alfa.di.uminho.pt/~afp98/ Advanced Functional Programming: 3rd International School], AFP'98, Braga, Portugal, September 12-19, 1998, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cs.uu.nl/~johanj/afp/afp4/ Advanced Functional Programming: 4th International School], AFP 2002, Oxford, UK, August 19-24, 2002, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cs.ut.ee/afp04/ Advanced Functional Programming: 5th International School], AFP 2004, Tartu, Estonia, August 14-21, 2004, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
More advanced materials available from the [[Conferences|conference proceedings]], and the [[Research papers]] collection.<br />
<br />
<br />
[[Category:Tutorials]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Tutorials&diff=23837Tutorials2008-11-02T22:58:20Z<p>Heisenbug: added "Learn You a Haskell"</p>
<hr />
<div>==Introductions to Haskell==<br />
<br />
These are the recommended places to start learning, short of buying a textbook.<br />
<br />
=== Best places to start ===<br />
<br />
;[http://darcs.haskell.org/yaht/yaht.pdf Yet Another Haskell Tutorial]<br />
:By Hal Daume III et al. A recommended tutorial for Haskell that is still under construction but covers already much ground. Also a classic text. Now available [http://en.wikibooks.org/wiki/Haskell/YAHT as a wikibook].<br />
<br />
;[http://en.wikibooks.org/wiki/Haskell Haskell Wikibook] <br />
:A communal effort by several authors to produce the definitive Haskell textbook. Its very much a work in progress at the moment, and contributions are welcome.<br />
<br />
;[http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/overview.html Write Yourself a Scheme in 48 Hours in Haskell]<br />
:A Haskell Tutorial, by Jonathan Tang. Most Haskell tutorials on the web seem to take a language-reference-manual approach to teaching. They show you the syntax of the language, a few language constructs, and then have you construct a few simple functions at the interactive prompt. The "hard stuff" of how to write a functioning, useful program is left to the end, or sometimes omitted entirely. This tutorial takes a different tack. You'll start off with command-line arguments and parsing, and progress to writing a fully-functional Scheme interpreter that implements a good-sized subset of R5RS Scheme. Along the way, you'll learn Haskell's I/O, mutable state, dynamic typing, error handling, and parsing features. By the time you finish, you should be fairly fluent in both Haskell and Scheme.<br />
<br />
;[http://learnyouahaskell.com Learn You a Haskell for Great Good!]<br />
: Nicely illustrated tutorial showing Haskell concepts while interacting in GHCi.<br />
<br />
=== More tutorials ===<br />
<br />
;[http://www.haskell.org/tutorial/ A Gentle Introduction to Haskell] :By Paul Hudak, John Peterson, and Joseph H. Fasel. The title is misleading. Some knowledge of another functional programming language is expected. The emphasis is on the type system and those features which are really new in Haskell (compared to other functional programming languages). A classic, but not for the faint of heart (it's not so gentle). Also available in [http://gorgonite.developpez.com/livres/traductions/haskell/gentle-haskell/ French] and [http://www.rsdn.ru/article/haskell/haskell_part1.xml Russian].<br />
<br />
;[[H-99: Ninety-Nine Haskell Problems]]<br />
:A collection of programming puzzles, with Haskell solutions. Solving these is a great way to get into Haskell programming.<br />
<br />
;[http://www.haskell.org/~pairwise/intro/intro.html Haskell Tutorial for C Programmers]<br />
:By Eric Etheridge. From the intro: "This tutorial assumes that the reader is familiar with C/C++, Python, Java, or Pascal. I am writing for you because it seems that no other tutorial was written to help students overcome the difficulty of moving from C/C++, Java, and the like to Haskell."<br />
<br />
;[http://www-106.ibm.com/developerworks/edu/os-dw-linuxhask-i.html Beginning Haskell] <br />
:From IBM developerWorks. This tutorial targets programmers of imperative languages wanting to learn about functional programming in the language Haskell. If you have programmed in languages such as C, Pascal, Fortran, C++, Java, Cobol, Ada, Perl, TCL, REXX, JavaScript, Visual Basic, or many others, you have been using an imperative paradigm. This tutorial provides a gentle introduction to the paradigm of functional programming, with specific illustrations in the Haskell 98 language. (Free registration required.)<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/teaching/Hskurs_toc.html Online Haskell Course] <br />
:By Ralf Hinze (in German).<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/tutorials.html Tutorial Papers in Functional Programming].<br />
:A collection of links to other Haskell tutorials, from John Hughes.<br />
<br />
;[http://www.cs.ou.edu/cs1323h/textbook/haskell.shtml Two Dozen Short Lessons in Haskell] <br />
:By Rex Page. A draft of a textbook on functional programming, available by ftp. It calls for active participation from readers by omitting material at certain points and asking the reader to attempt to fill in the missing information based on knowledge they have already acquired. The missing information is then supplied on the reverse side of the page. <br />
<br />
;[ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf Haskell-Tutorial] <br />
:By Damir Medak and Gerhard Navratil. The fundamentals of functional languages for beginners. <br />
<br />
;[http://video.s-inf.de/#FP.2005-SS-Giesl.(COt).HD_Videoaufzeichnung Video Lectures] <br />
:Lectures (in English) by Jürgen Giesl. About 30 hours in total, and great for learning Haskell. The lectures are 2005-SS-FP.V01 through 2005-SS-FP.V26. Videos 2005-SS-FP.U01 through 2005-SS-FP.U11 are exercise answer sessions, so you probably don't want those.<br />
<br />
;[http://www.cs.utoronto.ca/~trebla/fp/ Albert's Functional Programming Course] <br />
:A 15 lesson introduction to most aspects of Haskell.<br />
<br />
;[http://www.iceteks.com/articles.php/haskell/1 Introduction to Haskell]<br />
:By Chris Dutton, An "attempt to bring the ideas of functional programming to the masses here, and an experiment in finding ways to make it easy and interesting to follow".<br />
<br />
;[http://www.csc.depauw.edu/~bhoward/courses/0203Spring/csc122/haskintro/ An Introduction to Haskell]<br />
:A brief introduction, by Brian Howard.<br />
<br />
;[http://web.syntaxpolice.org/lectures/haskellTalk/slides/index.html Introduction to Haskell]<br />
:By Isaac Jones (2003).<br />
<br />
;[http://www.linuxjournal.com/article/9096 Translating Haskell into English]<br />
:By Shannon Behrens, a glimpse of the Zen of Haskell, without requiring that they already be Haskell converts.<br />
<br />
;[http://www.shlomifish.org/lecture/Perl/Haskell/slides/ Haskell for Perl Programmers]<br />
:Brief introduction to Haskell, with a view to what perl programmers are interested in<br />
<br />
;[http://lisperati.com/haskell/ How To Organize a Picnic on a Computer]<br />
:Fun introduction to Haskell, step by step building of a program to seat people at a planned picnic, based on their similarities using data from a survey and a map of the picnic location.<br />
<br />
;[http://cs.wwc.edu/KU/PR/Haskell.html Haskell Tutorial]<br />
<br />
;[http://www.lisperati.com/haskell/ Conrad Barski's Haskell tutorial .. with robots]<br />
<br />
;[[Media:Introduction.pdf|Frederick Ross's Haskell introduction]]<br />
<br />
== Motivation for using Haskell ==<br />
<br />
;[http://www.md.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters] <br />
:By [http://www.md.chalmers.se/~rjmh/ John Hughes], The Computer Journal, Vol. 32, No. 2, 1989, pp. 98 - 107. Also in: David A. Turner (ed.): Research Topics in Functional Programming, Addison-Wesley, 1990, pp. 17 - 42.<BR> Exposes the advantages of functional programming languages. Demonstrates how higher-order functions and lazy evaluation enable new forms of modularization of programs.<br />
<br />
;[[Why Haskell matters]] <br />
:Discussion of the advantages of using Haskell in particular. An excellent article.<br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1997/224/index.html Higher-order + Polymorphic = Reusable] <br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson]. Unpublished, May 1997.<BR> <STRONG>Abstract:</STRONG> This paper explores how certain ideas in object oriented languages have their correspondents in functional languages. In particular we look at the analogue of the iterators of the C++ standard template library. We also give an example of the use of constructor classes which feature in Haskell 1.3 and Gofer.<br />
<br />
;[http://www-128.ibm.com/developerworks/java/library/j-cb07186.html Explore functional programming with Haskell]<br />
:Introduction to the benefits of functional programming in Haskell by Bruce Tate.<br />
<br />
== Blog articles ==<br />
<br />
There are a large number of tutorials covering diverse Haskell topics<br />
published as blogs. Some of the best of these articles are collected<br />
here:<br />
<br />
;[[Blog articles]]<br />
<br />
==Practical Haskell==<br />
<br />
These tutorials examine using Haskell to writing complex real-world applications<br />
<br />
;[http://research.microsoft.com/%7Esimonpj/Papers/marktoberdorf Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell]<br />
:Simon Peyton Jones. Presented at the 2000 Marktoberdorf Summer School. In "Engineering theories of software construction", ed Tony Hoare, Manfred Broy, Ralf Steinbruggen, IOS Press, ISBN 1-58603-1724, 2001, pp47-96. The standard reference for monadic IO in GHC/Haskell. <br><strong>Abstract:</strong>Functional programming may be beautiful, but to write real applications we must grapple with awkward real-world issues: input/output, robustness, concurrency, and interfacing to programs written in other languages.<br />
<br />
;[[Hitchhikers Guide to the Haskell]]<br />
: Tutorial for C/Java/OCaml/... programers by Dmitry Astapov. From the intro: "This text intends to introduce the reader to the practical aspects of Haskell from the very beginning (plans for the first chapters include: I/O, darcs, Parsec, QuickCheck, profiling and debugging, to mention a few)".<br />
<br />
;[http://haskell.org/haskellwiki/IO_inside Haskell I/O inside: Down the Rabbit's Hole]<br />
:By Bulat Ziganshin (2006), a comprehensive tutorial on using IO monad.<br />
<br />
;[http://web.archive.org/web/20060622030538/http://www.reid-consulting-uk.ltd.uk/docs/ffi.html A Guide to Haskell's Foreign Function Interface]<br />
:A guide to using the foreign function interface extension, using the rich set of functions in the Foreign libraries, design issues, and FFI preprocessors.<br />
<br />
;[http://blogs.nubgames.com/code/?p=22 Haskell IO for imperative programmers]<br />
:A short introduction to IO from the perspective of an imperative programmer.<br />
<br />
;[[A brief introduction to Haskell|A Brief Introduction to Haskell]]<br />
:A translation of the article, [http://www.cs.jhu.edu/~scott/pl/lectures/caml-intro.html Introduction to OCaml], to Haskell.<br />
<br />
;[[Roll your own IRC bot]]<br />
:This tutorial is designed as a practical guide to writing real world code in Haskell and hopes to intuitively motivate and introduce some of the advanced features of Haskell to the novice programmer, including monad transformers. Our goal is to write a concise, robust and elegant IRC bot in Haskell.<br />
<br />
;[http://haskell.org/gtk2hs/docs/tutorial/glade/ Glade Tutorial (GUI Programming)]<br />
:For the absolute beginner in both Glade and Gtk2Hs. Covers the basics of Glade and how to access a .glade file and widgets in Gtk2Hs. Estimated learning time: 2 hours.<br />
;[http://www.muitovar.com/glade/es-index.html Tutorial de Glade]<br />
:A Spanish translation of the Glade tutorial<br />
<br />
;[http://www.muitovar.com/index.xhtml#sec3 Gtk2Hs Tutorial]<br />
: An extensive Gtk2Hs programming guide, based on the GTK+2.0 tutorial by Tony Gale and Ian Main. This tutorial on GUI programming with Gtk2Hs has 22 chapters in 7 sections, plus an appendix on starting drawing with Cairo. A Spanish translation and source code of the examples are also available.<br />
<br />
;Applications of Functional Programming<br />
:Colin Runciman and David Wakeling (ed.), UCL Press, 1995, ISBN 1-85728-377-5 HB. From the cover:<blockquote>This book is unique in showcasing real, non-trivial applications of functional programming using the Haskell language. It presents state-of-the-art work from the FLARE project and will be an invaluable resource for advanced study, research and implementation.</blockquote><br />
<br />
;[[DealingWithBinaryData]] a guide to bytestrings, the various <tt>Get</tt> monads and the <tt>Put</tt> monad.<br />
<br />
===Testing===<br />
<br />
;[http://blog.moertel.com/articles/2006/10/31/introductory-haskell-solving-the-sorting-it-out-kata Small overview of QuickCheck]<br />
<br />
;[[Introduction to QuickCheck]]<br />
<br />
==Reference material==<br />
<br />
;[http://haskell.org/haskellwiki/Category:Tutorials A growing list of Haskell tutorials on a diverse range of topics]<br />
:Available on this wiki<br />
<br />
;[http://haskell.org/haskellwiki/Category:How_to "How to"-style tutorials and information]<br />
<br />
;[http://undergraduate.csse.uwa.edu.au/units/230.301/lectureNotes/tourofprelude.html A Tour of the Haskell Prelude (basic functions)] <br />
:By Bernie Pope and Arjan van IJzendoorn.<br />
<br />
;[http://cs.anu.edu.au/Student/comp1100/haskell/tourofsyntax.html Tour of the Haskell Syntax] <br />
:By Arjan van IJzendoorn.<br />
<br />
;[http://zvon.org/other/haskell/Outputglobal/index.html Haskell Reference] <br />
:By Miloslav Nic.<br />
<br />
;[http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions]<br />
:By Henk-Jan van Tuyl.<br />
<br />
;[http://www.cse.unsw.edu.au/~en1000/haskell/inbuilt.html Useful Haskell functions]<br />
:An explanation for beginners of many Haskell functions that are predefined in the Haskell Prelude.<br />
<br />
;[http://www.cs.chalmers.se/Cs/Grundutb/Kurser/d1pt/d1pta/ListDoc/ Haskell's Standard List Functions]<br />
:A tour of the standard Haskell functions, directed by what you want to achieve<br />
<br />
;[http://haskell.org/ghc/docs/latest/html/libraries/ Documentation for the standard libraries]<br />
:Complete documentation of the standard Haskell libraries.<br />
<br />
;[http://www.haskell.org/haskellwiki/Category:Idioms Haskell idioms]<br />
:A collection of articles describing some common Haskell idioms. Often quite advanced.<br />
<br />
;[http://www.haskell.org/haskellwiki/Blow_your_mind Useful idioms]<br />
:A collection of short, useful Haskell idioms.<br />
<br />
;[http://www.haskell.org/haskellwiki/Programming_guidelines Programming guidelines]<br />
:Some Haskell programming and style conventions.<br />
<br />
;[http://www.md.chalmers.se/~rjmh/Combinators/LightningTour/index.htm Lightning Tour of Haskell]<br />
:By John Hughes, as part of a Chalmers programming course<br />
<br />
;[http://www.cs.chalmers.se/~augustss/AFP/manuals/haskeller.dvi.gz The Little Haskeller] <br />
:By Cordelia Hall and John Hughes. 9. November 1993, 26 pages. An introduction using the Chalmers Haskell B interpreter (hbi). Beware that it relies very much on the user interface of hbi which is quite different for other Haskell systems, and the tutorials cover Haskell 1.2 , not Haskell 98.<br />
<br />
;[http://www.cs.uu.nl/people/jeroen/courses/fp-eng.pdf Functional Programming]<br />
:By Jeroen Fokker, 1995. (153 pages, 600 KB). Textbook for learning functional programming with Gofer (an older implementation of Haskell). Here without Chapters&nbsp;6 and&nbsp;7.<br />
<br />
== Comparisons to other languages ==<br />
<br />
Articles constrasting feature of Haskell with other languages.<br />
<br />
;[http://programming.reddit.com/goto?id=nq1k Haskell versus Scheme]<br />
:Mark C. Chu-Carroll, Haskell and Scheme: Which One and Why?<br />
<br />
;[http://wiki.python.org/moin/PythonVsHaskell Comparing Haskell and Python]<br />
:A short overview of similarities and differences between Haskell and Python.<br />
<br />
;[http://programming.reddit.com/goto?id=nwm2 Monads in OCaml]<br />
:Syntax extension for monads in OCaml<br />
<br />
;[http://www.shlomifish.org/lecture/Perl/Haskell/slides/ Haskell for Perl programmers]<br />
:Short intro for perlers<br />
<br />
;[[A_brief_introduction_to_Haskell|Introduction to Haskell]] versus [http://www.cs.jhu.edu/~scott/pl/lectures/caml-intro.html Introduction to OCaml].<br />
<br />
;[http://www.thaiopensource.com/relaxng/derivative.html An algorithm for RELAX NG validation]<br />
:by James Clark (of RELAX NG fame). Describes an algorithm for validating an XML document against a RELAX NG schema, uses Haskell to describe the algorithm. The algorithm in Haskell and Java is then [http://www.donhopkins.com/drupal/node/117 discussed here].<br />
<br />
;[http://mult.ifario.us/articles/2006/10/11/first-steps-with-haskell-for-web-applications Haskell + FastCGI versus Ruby on Rails]<br />
:A short blog entry documenting performance results with ruby on rails and Haskell with fastcgi<br />
<br />
;[http://haskell.org/papers/NSWC/jfp.ps Haskell vs. Ada vs. C++ vs. Awk vs. ..., An Experiment in Software Prototyping Productivity] (postscript)<br />
:Paul Hudak and Mark P. Jones, 16 pages.<blockquote>Description of the results of an experiment in which several conventional programming languages, together with the functional language Haskell, were used to prototype a Naval Surface Warfare Center requirement for Geometric Region Servers. The resulting programs and development metrics were reviewed by a committee chosen by the US Navy. The results indicate that the Haskell prototype took significantly less time to develop and was considerably more concise and easier to understand than the corresponding prototypes written in several different imperative languages, including Ada and C++. </blockquote> <br />
<br />
;[http://www.osl.iu.edu/publications/prints/2003/comparing_generic_programming03.pdf A Comparative Study of Language Support for Generic Programming] (pdf)<br />
:Ronald Garcia, Jaakko Jrvi, Andrew Lumsdaine, Jeremy G. Siek, and Jeremiah Willcock. In Proceedings of the 2003 ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA'03), October 2003.<blockquote>An interesting comparison of generic programming support across languages, including: Haskell, SML, C++, Java, C#. Haskell supports all constructs described in the paper -- the only language to do so. </blockquote><br />
<br />
;[http://homepages.inf.ed.ac.uk/wadler/realworld/index.html Functional Programming in the Real World]<br />
:A list of functional programs applied to real-world tasks. The main criterion for being real-world is that the program was written primarily to perform some task, not primarily to experiment with functional programming. Functional is used in the broad sense that includes both `pure' programs (no side effects) and `impure' (some use of side effects). Languages covered include CAML, Clean, Erlang, Haskell, Miranda, Scheme, SML, and others.<br />
<br />
;[http://www.defmacro.org/ramblings/lisp-in-haskell.html Lisp in Haskell]<br />
:Writing A Lisp Interpreter In Haskell, a tutorial<br />
<br />
== Teaching Haskell ==<br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1997/208/index.html Where do I begin? A problem solving approach to teaching functional programming]<br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson]. In Krzysztof Apt, Pieter Hartel, and Paul Klint, editors, First International Conference on Declarative Programming Languages in Education. Springer-Verlag, September 1997. <br> <STRONG>Abstract:</STRONG> This paper introduces a problem solving method for teaching functional programming, based on Polya's `How To Solve It', an introductory investigation of mathematical method. We first present the language independent version, and then show in particular how it applies to the development of programs in Haskell. The method is illustrated by a sequence of examples and a larger case study. <br />
<br />
;[http://www.cs.ukc.ac.uk/pubs/1995/214/index.html Functional programming through the curriculum]<br />
:By [http://www.cs.ukc.ac.uk/people/staff/sjt/index.html Simon Thompson] and Steve Hill. In Pieter H. Hartel and Rinus Plasmeijer, editors, Functional Programming Languages in Education, LNCS 1022, pages 85-102. Springer-Verlag, December 1995. <br> <STRONG>Abstract:</STRONG> This paper discusses our experience in using a functional language in topics across the computer science curriculum. After examining the arguments for taking a functional approach, we look in detail at four case studies from different areas: programming language semantics, machine architectures, graphics and formal languages. <br />
<br />
;[http://www.cse.unsw.edu.au/~chak/papers/CK02a.html The Risks and Benefits of Teaching Purely Functional Programming in First Year]<br />
:By [http://www.cse.unsw.edu.au/~chak Manuel M. T. Chakravarty] and [http://www.cse.unsw.edu.au/~keller Gabriele Keller]. Journal of Functional Programming 14(1), pp 113-123, 2004. An earlier version of this paper was presented at Functional and Declarative Programming in Education (FDPE02). <br> <strong>Abstract</strong> We argue that teaching purely functional programming as such in freshman courses is detrimental to both the curriculum as well as to promoting the paradigm. Instead, we need to focus on the more general aims of teaching elementary techniques of programming and essential concepts of computing. We support this viewpoint with experience gained during several semesters of teaching large first-year classes (up to 600 students) in Haskell. These classes consisted of computer science students as well as students from other disciplines. We have systematically gathered student feedback by conducting surveys after each semester. This article contributes an approach to the use of modern functional languages in first year courses and, based on this, advocates the use of functional languages in this setting.<br />
<br />
<br />
==Using monads==<br />
<br />
See also the [[Monad]] HaskellWiki page.<br />
<br />
<br />
===Recommended tutorials===<br />
<br />
;[http://www.haskell.org/all_about_monads/html/index.html All About Monads] <br />
:By Jeff Newbern. This tutorial aims to explain the concept of a monad and its application to functional programming in a way that is easy to understand and useful to beginning and intermediate Haskell programmers. Familiarity with the Haskell language is assumed, but no prior experience with monads is required. <br />
<br />
;[[Monads as computation]]<br />
:A tutorial which gives a broad overview to motivate the use of monads as an abstraction in functional programming and describe their basic features. It makes an attempt at showing why they arise naturally from some basic premises about the design of a library.<br />
<br />
;[[Monads as containers]]<br />
:A tutorial describing monads from a rather different perspective: as an abstraction of container-types, rather than an abstraction of types of computation.<br />
<br />
;[http://uebb.cs.tu-berlin.de/~magr/pub/Transformers.en.html Monad Transformers Step by Step]<br />
:By Martin Grabm&uuml;ller. A small tutorial on using monad transformers. In contrast to others found on the web, it concentrates on using them, not on their implementation.<br />
<br />
===Parser===<br />
<br />
;[http://www.haskell.org/sitewiki/images/c/c6/ICMI45-paper-en.pdf The Parser monad and other monad (i.e. a monad with state and I/O string)]. <br />
:The parser monad is used to build modular, flexible, parsers. <br />
<br />
;[http://www.haskell.org/sitewiki/images/c/c6/ICMI45-paper-en.pdf How to build a monadic interpreter in one day] (pdf)<br />
:By Dan Popa. A small tutorial on how to build a language in one day, using the Parser Monad in the front end and a monad with state and I/O string in the back end. Read it if you are interested in learning: <br />
:# language construction and <br />
:# interpreter construction<br />
<br />
===More tutorials===<br />
<br />
;[http://stefan-klinger.de/files/monadGuide.pdf The Haskell Programmer's Guide to the IO Monad - Don't Panic.] <br />
:By Stefan Klinger. This report scratches the surface of category theory, an abstract branch of algebra, just deep enough to find the monad structure. It seems well written.<br />
<br />
;[http://www.prairienet.org/~dsb/monads.htm A (hopefully) painless introduction to monads] <br />
:By Dan Bensen. A straightforward beginner's guide with intuitive explanations and examples.<br />
<br />
;[http://www-users.mat.uni.torun.pl/~fly/materialy/fp/haskell-doc/Monads.html What the hell are Monads?] <br />
:By Noel Winstanley. A basic introduction to monads, monadic programming and IO. This introduction is presented by means of examples rather than theory, and assumes a little knowledge of Haskell. <br />
<br />
;[http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm Monads for the Working Haskell Programmer -- a short tutorial]<br />
:By Theodore Norvell. <br />
<br />
;[http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html You Could Have Invented Monads! (And Maybe You Already Have.)]<br />
:A short tutorial on monads, introduced from a pragmatic approach, with less category theory references <br />
<br />
;[http://www.cs.chalmers.se/~augustss/AFP/monads.html Systematic Design of Monads]<br />
:By John Hughes and Magnus Carlsson. Many useful monads can be designed in a systematic way, by successively adding facilities to a trivial monad. The capabilities that can be added in this way include state, exceptions, backtracking, and output. Here we give a brief description of the trivial monad, each kind of extension, and sketches of some interesting operations that each monad supports.<br />
<br />
;[[Meet Bob The Monadic Lover]]<br />
:By Andrea Rossato. A by-the-author-supposed-to-be funny and short introduction to Monads, with code but without any reference to category theory: what monads look like and what they are useful for, from the perspective of a ... lover. (There is also the slightly more serious [[The Monadic Way]] by the same author.)<br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2006-November/019190.html Monstrous Monads]<br />
:Andrew Pimlott's humourous introduction to monads, using the metaphor of "monsters".<br />
<br />
;Computational monads on Reddit, by [http://programming.reddit.com/info/ox6s/comments/coxiv tmoertel] and [http://programming.reddit.com/info/ox6s/comments/coxoh dons].<br />
<br />
;[http://www.loria.fr/~kow/monads/index.html Of monads and space suits]<br />
:By Eric Kow.<br />
<br />
;[[The Monadic Way]]<br />
<br />
;[http://www.alpheccar.org/fr/posts/show/60 Three kind of monads] : sequencing, side effects or containers<br />
<br />
;[[Simple monad examples]]<br />
<br />
;[http://en.wikipedia.org/wiki/Monads_in_functional_programming Article on monads on Wikipedia]<br />
<br />
;[[IO inside]] page<br />
:Explains why I/O in Haskell is implemented with a monad.<br />
<br />
;[http://haskell.org/haskellwiki/Blog_articles#Monads Blog articles]<br />
<br />
;[[Monad Transformers Explained]]<br />
<br />
;[http://www.muitovar.com/monad/moncow.xhtml The Greenhorn's Guide to becoming a Monad Cowboy]<br />
:Covers basics in a ''for dummies'' style. Estimated learning time 1-2 days.<br />
<br />
<br />
See also [[Research papers/Monads and arrows]]<br />
<br />
==Workshops on advanced functional programming==<br />
<br />
;[http://compilers.iecc.com/comparch/article/95-04-024 Advanced Functional Programming: 1st International Spring School on Advanced Functional Programming Techniques], Bastad, Sweden, May 24 - 30, 1995. Tutorial Text (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cse.ogi.edu/PacSoft/conf/summerschool96.html Advanced Functional Programming: 2nd International School], Olympia, Wa, Usa, August 26-30, 1996 Tutorial Text (Lecture Notes in Computer Science) <br />
<br />
;[http://alfa.di.uminho.pt/~afp98/ Advanced Functional Programming: 3rd International School], AFP'98, Braga, Portugal, September 12-19, 1998, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cs.uu.nl/~johanj/afp/afp4/ Advanced Functional Programming: 4th International School], AFP 2002, Oxford, UK, August 19-24, 2002, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
;[http://www.cs.ut.ee/afp04/ Advanced Functional Programming: 5th International School], AFP 2004, Tartu, Estonia, August 14-21, 2004, Revised Lectures (Lecture Notes in Computer Science) <br />
<br />
More advanced materials available from the [[Conferences|conference proceedings]], and the [[Research papers]] collection.<br />
<br />
<br />
[[Category:Tutorials]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=How_to_write_a_Haskell_program&diff=22569How to write a Haskell program2008-08-22T10:00:43Z<p>Heisenbug: fix console command to create the file proper</p>
<hr />
<div>A guide to creating a new Haskell project or program.<br />
<br />
== Recommended tools ==<br />
<br />
Almost all new Haskell projects use the following tools. Each is<br />
intrinsically useful, but using a set of common tools also helps<br />
everyone by increasing productivity, and you're more likely to get<br />
patches.<br />
<br />
=== Revision control ===<br />
<br />
Use [http://darcs.net Darcs] unless you have a specific reason not to.<br />
It's much more powerful than most competing systems (and it's written in Haskell).<br />
<br />
=== Build system ===<br />
<br />
[[Image:Cabal-With-Text-small.png|frame|Built with Cabal]]<br />
<br />
Use [http://haskell.org/cabal Cabal].<br />
You should read at least the start of section 2 of the [http://www.haskell.org/ghc/docs/latest/html/Cabal/index.html Cabal User's Guide].<br />
<br />
=== Documentation ===<br />
<br />
For libraries, use [http://haskell.org/haddock Haddock]. We recommend<br />
using the latest version of haddock (currently 0.8).<br />
<br />
=== Testing ===<br />
<br />
You can use [http://www.md.chalmers.se/~rjmh/QuickCheck/ QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. To test impure code, use [http://hunit.sourceforge.net/ HUnit]. <br />
<br />
To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/2006/09/01/simple-unit-testing-in-haskell/ Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell.<br />
<br />
=== Distribution ===<br />
<br />
The new standard mechanism for distributing Haskell libraries and<br />
applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can<br />
host your cabalised tarball releases, and link to any library<br />
dependencies your code has.<br />
<br />
== Structure of a simple project ==<br />
<br />
The basic structure of a new Haskell project can be adopted from<br />
[http://semantic.org/hnop/ HNop], the minimal Haskell project. It<br />
consists of the following files, for the mythical project "haq".<br />
<br />
* Haq.hs -- the main haskell source file<br />
* haq.cabal -- the cabal build description<br />
* Setup.hs -- build script itself<br />
* _darcs -- revision control<br />
* README -- info<br />
* LICENSE -- license<br />
<br />
Of course, you can elaborate on this, with subdirectories and multiple<br />
modules. See [[Structure of a Haskell project]] for an example of a larger project's directory structure.<br />
<br />
Here is a transcript that shows how you'd create a minimal darcs and cabalised<br />
Haskell project for the cool new Haskell program "haq", build it,<br />
install it and release.<br />
<br />
The new tool 'mkcabal' automates all this for you, but you should<br />
understand all the parts even so. <br />
<br />
We will now walk through the creation of the infrastructure for a simple<br />
Haskell executable. Advice for libraries follows after.<br />
<br />
=== Create a directory ===<br />
<br />
Create somewhere for the source:<br />
<br />
<code><br />
$ mkdir haq<br />
$ cd haq<br />
</code><br />
<br />
=== Write some Haskell source ===<br />
<br />
Write your program:<br />
<br />
<haskell><br />
$ cat > Haq.hs<br />
--<br />
-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons<br />
-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
--<br />
import System.Environment<br />
<br />
-- | 'main' runs the main program<br />
main :: IO ()<br />
main = getArgs >>= print . haqify . head<br />
<br />
haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
=== Stick it in darcs ===<br />
<br />
Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):<br />
<br />
<code><br />
$ darcs init<br />
$ darcs add Haq.hs <br />
$ darcs record<br />
addfile ./Haq.hs<br />
Shall I record this change? (1/?) [ynWsfqadjkc], or ? for help: y<br />
hunk ./Haq.hs 1<br />
+--<br />
+-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons<br />
+-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
+--<br />
+import System.Environment<br />
+<br />
+-- | 'main' runs the main program<br />
+main :: IO ()<br />
+main = getArgs >>= print . haqify . head<br />
+<br />
+haqify s = "Haq! " ++ s<br />
Shall I record this change? (2/?) [ynWsfqadjkc], or ? for help: y<br />
What is the patch name? Import haq source<br />
Do you want to add a long comment? [yn]n<br />
Finished recording patch 'Import haq source'<br />
</code><br />
<br />
And we can see that darcs is now running the show:<br />
<br />
<code><br />
$ ls<br />
Haq.hs _darcs<br />
</code><br />
<br />
=== Add a build system ===<br />
<br />
Create a .cabal file describing how to build your project:<br />
<br />
<code><br />
$ cat > haq.cabal<br />
Name: haq<br />
Version: 0.0<br />
Description: Super cool mega lambdas<br />
License: GPL<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Depends: base<br />
Build-Type: Simple<br />
<br />
Executable: haq<br />
Main-is: Haq.hs<br />
ghc-options: -O<br />
</code><br />
<br />
(If your package uses other packages, e.g. <tt>haskell98</tt>, you'll need to add them to the <tt>Build-Depends:</tt> field as a comma separated list.)<br />
Add a <tt>Setup.lhs</tt> that will actually do the building:<br />
<br />
<haskell><br />
$ cat > Setup.lhs<br />
#! /usr/bin/env runhaskell<br />
<br />
> import Distribution.Simple<br />
> main = defaultMain<br />
</haskell><br />
Cabal allows either <tt>Setup.hs</tt> or <tt>Setup.lhs</tt>, but we recommend that you write the setup file this way so that Unix shells can execute it directly.<br />
<br />
Now would also be a good time to add a LICENSE file and a README file. Examples are in the tarball for HNop.<br />
<br />
Record your changes:<br />
<br />
<code><br />
$ darcs add haq.cabal Setup.lhs LICENSE README<br />
$ darcs record --all<br />
What is the patch name? Add a build system<br />
Do you want to add a long comment? [yn]n<br />
Finished recording patch 'Add a build system'<br />
</code><br />
<br />
=== Build your project ===<br />
<br />
Now build it!<br />
<br />
<code><br />
$ runhaskell Setup.lhs configure --prefix=$HOME<br />
$ runhaskell Setup.lhs build<br />
$ runhaskell Setup.lhs install<br />
</code><br />
<br />
This will install your newly minted haq program in $HOME/bin.<br />
<br />
=== Run it ===<br />
<br />
And now you can run your cool project:<br />
<code><br />
$ haq me<br />
"Haq! me"<br />
</code><br />
<br />
You can also run it in-place, even if you skip the install phase:<br />
<code><br />
$ dist/build/haq/haq you<br />
"Haq! you"<br />
</code><br />
<br />
=== Build some haddock documentation ===<br />
<br />
Generate some API documentation into dist/doc/*<br />
<br />
<code><br />
$ runhaskell Setup.lhs haddock<br />
</code><br />
<br />
which generates files in dist/doc/ including:<br />
<br />
<code><br />
$ w3m -dump dist/doc/html/haq/Main.html<br />
haq Contents Index<br />
Main<br />
<br />
Synopsis<br />
main :: IO ()<br />
<br />
Documentation<br />
<br />
main :: IO ()<br />
main runs the main program<br />
<br />
Produced by Haddock version 0.7<br />
</code><br />
<br />
No output? Make sure you have actually installed haddock. It is a separate program, not something that comes with Cabal. Note that the stylized comment in the source gets picked up by Haddock.<br />
<br />
=== Add some automated testing: QuickCheck ===<br />
<br />
We'll use QuickCheck to specify a simple property of our Haq.hs code. Create a tests module, Tests.hs, with some QuickCheck boilerplate:<br />
<br />
<haskell><br />
$ cat > Tests.hs<br />
import Char<br />
import List<br />
import Test.QuickCheck<br />
import Text.Printf<br />
<br />
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests<br />
<br />
instance Arbitrary Char where<br />
arbitrary = choose ('\0', '\128')<br />
coarbitrary c = variant (ord c `rem` 4)<br />
</haskell><br />
<br />
Now let's write a simple property:<br />
<br />
<haskell><br />
$ cat >> Tests.hs <br />
-- reversing twice a finite list, is the same as identity<br />
prop_reversereverse s = (reverse . reverse) s == id s<br />
where _ = s :: [Int]<br />
<br />
-- and add this to the tests list<br />
tests = [("reverse.reverse/id", test prop_reversereverse)]<br />
</haskell><br />
<br />
We can now run this test, and have QuickCheck generate the test data:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : OK, passed 100 tests.<br />
</code><br />
<br />
Let's add a test for the 'haqify' function:<br />
<br />
<haskell><br />
-- Dropping the "Haq! " string is the same as identity<br />
prop_haq s = drop (length "Haq! ") (haqify s) == id s<br />
where haqify s = "Haq! " ++ s<br />
<br />
tests = [("reverse.reverse/id", test prop_reversereverse)<br />
,("drop.haq/id", test prop_haq)]<br />
</haskell><br />
<br />
and let's test that:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : OK, passed 100 tests.<br />
drop.haq/id : OK, passed 100 tests.<br />
</code><br />
<br />
Great!<br />
<br />
=== Running the test suite from darcs ===<br />
<br />
We can arrange for darcs to run the test suite on every commit:<br />
<br />
<code><br />
$ darcs setpref test "runhaskell Tests.hs"<br />
Changing value of test from '' to 'runhaskell Tests.hs'<br />
</code><br />
<br />
will run the full set of QuickChecks.<br />
If your test requires it, you may need to ensure other things are built too -- for example:<code>darcs setpref test "alex Tokens.x;happy Grammar.y;runhaskell Tests.hs"</code>.<br />
You will encounter that this way a darcs patch is also accepted if a QuickCheck test fails.<br />
You have two choices to [http://www.haskell.org/pipermail/haskell-cafe/2007-October/033834.html work around] this:<br />
* Use <hask>quickCheck'</hask> from the package QuickCheck-2 and call <hask>exitWithFailure</hask> if it return <hask>False</hask>.<br />
* Keep the test program as it is, and implement the failure on the shell level:<br />
: <code>runhaskell Tests.hs | tee test.log && if grep Falsifiable test.log >/dev/null; then exit 1; fi</code><br />
<br />
Let's commit a new patch:<br />
<br />
<code><br />
$ darcs add Tests.hs<br />
$ darcs record --all<br />
What is the patch name? Add testsuite<br />
Do you want to add a long comment? [yn]n<br />
Running test...<br />
reverse.reverse/id : OK, passed 100 tests.<br />
drop.haq/id : OK, passed 100 tests.<br />
Test ran successfully.<br />
Looks like a good patch.<br />
Finished recording patch 'Add testsuite'<br />
</code><br />
<br />
Excellent: now, patches must pass the test suite before they can be committed.<br />
<br />
=== Tag the stable version, create a tarball, and sell it! ===<br />
<br />
Tag the stable version:<br />
<br />
<code><br />
$ darcs tag<br />
What is the version name? 0.0<br />
Finished tagging patch 'TAG 0.0'<br />
</code><br />
<br />
==== Create a tarball ====<br />
You can do this using either Cabal or darcs, or even an explicit <tt>tar</tt> command.<br />
<br />
===== Using Cabal =====<br />
<br />
Since the code is cabalised, we can create a tarball with Cabal<br />
directly:<br />
<br />
<code><br />
$ runhaskell Setup.lhs sdist<br />
Building source dist for haq-0.0...<br />
Source tarball created: dist/haq-0.0.tar.gz<br />
</code><br />
This has the advantage that Cabal will do a bit more checking, and<br />
ensure that the tarball has the structure that HackageDB expects. <br />
Note that it does require the LICENSE file to exist.<br />
It packages up the files needed to build the project; to include other files (such as <tt>Test.hs</tt> in the above example, and our README), we need to add:<br />
<br />
<code><br />
extra-source-files: Tests.hs README<br />
</code><br />
<br />
to the .cabal file to have everything included.<br />
<br />
===== Using darcs =====<br />
<br />
Alternatively, you can use darcs:<br />
<code><br />
$ darcs dist -d haq-0.0<br />
Created dist as haq-0.0.tar.gz<br />
</code><br />
<br />
And you're all set up!<br />
<br />
==== Check that your source package is complete ====<br />
<br />
Just to make sure everything works, try building the source package in some temporary directory:<br />
<code><br />
$ tar xzf haq-0.0.tar.gz<br />
$ cd haq-0.0<br />
$ runhaskell Setup.lhs configure<br />
$ runhaskell Setup.lhs build<br />
</code><br />
and for packages containing libraries,<br />
<code><br />
$ runhaskell Setup.lhs haddock<br />
</code><br />
<br />
==== Upload your package to Hackage ====<br />
<br />
Whichever of the above methods you've used to create your package, you can upload it to the Hackage package collection via a [http://hackage.haskell.org/packages/upload.html web interface].<br />
You may wish to use the package checking interface there first, and fix things it warns about, before uploading your package.<br />
<br />
=== Summary ===<br />
<br />
The following files were created:<br />
<br />
$ ls<br />
Haq.hs Tests.hs dist haq.cabal<br />
Setup.lhs _darcs haq-0.0.tar.gz<br />
<br />
== Libraries ==<br />
<br />
The process for creating a Haskell library is almost identical. The differences<br />
are as follows, for the hypothetical "ltree" library:<br />
<br />
=== Hierarchical source ===<br />
<br />
The source should live under a directory path that fits into the<br />
existing [[Hierarchical module names|module layout guide]].<br />
So we would create the following directory structure, for the module<br />
Data.LTree:<br />
<br />
$ mkdir Data<br />
$ cat > Data/LTree.hs <br />
module Data.LTree where<br />
<br />
So our Data.LTree module lives in Data/LTree.hs<br />
<br />
=== The Cabal file ===<br />
<br />
Cabal files for libraries list the publically visible modules, and have<br />
no executable section:<br />
<br />
$ cat > ltree.cabal <br />
Name: ltree<br />
Version: 0.1<br />
Description: Lambda tree implementation<br />
License: BSD3<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Depends: base<br />
Exposed-modules: Data.LTree<br />
ghc-options: -Wall -O<br />
<br />
We can thus build our library:<br />
<br />
$ runhaskell Setup.lhs configure --prefix=$HOME<br />
$ runhaskell Setup.lhs build <br />
Preprocessing library ltree-0.1...<br />
Building ltree-0.1...<br />
[1 of 1] Compiling Data.LTree ( Data/LTree.hs, dist/build/Data/LTree.o )<br />
/usr/bin/ar: creating dist/build/libHSltree-0.1.a<br />
<br />
and our library has been created as a object archive. Now install it:<br />
<br />
$ runhaskell Setup.lhs install<br />
Installing: /home/dons/lib/ltree-0.1/ghc-6.6 & /home/dons/bin ltree-0.1...<br />
Registering ltree-0.1...<br />
Reading package info from ".installed-pkg-config" ... done.<br />
Saving old package config file... done.<br />
Writing new package config file... done.<br />
<br />
And we're done! You can use your new library from, for example, ghci:<br />
<br />
$ ghci -package ltree<br />
Prelude> :m + Data.LTree<br />
Prelude Data.LTree> <br />
<br />
The new library is in scope, and ready to go.<br />
<br />
=== More complex build systems ===<br />
<br />
For larger projects, you may want to store source trees in subdirectories. This can be done simply by creating a directory -- for example, "src" -- into which you will put your src tree.<br />
<br />
To have Cabal find this code, you add the following line to your Cabal<br />
file:<br />
<br />
hs-source-dirs: src<br />
<br />
You can also set up Cabal to run configure scripts, among other features. For more information consult the<br />
[http://www.haskell.org/ghc/docs/latest/html/Cabal/index.html Cabal documentation].<br />
<br />
== Automation ==<br />
<br />
A tool to automatically populate a new cabal project is available<br />
(beta!):<br />
<br />
darcs get http://code.haskell.org/~dons/code/mkcabal<br />
<br />
Usage is:<br />
<br />
<code><br />
$ mkcabal<br />
Project name: haq<br />
What license ["GPL","LGPL","BSD3","BSD4","PublicDomain","AllRightsReserved"] ["BSD3"]: <br />
What kind of project [Executable,Library] [Executable]: <br />
Is this your name? - "Don Stewart " [Y/n]: <br />
Is this your email address? - "<dons@cse.unsw.edu.au>" [Y/n]: <br />
Created Setup.lhs and haq.cabal<br />
$ ls<br />
Haq.hs LICENSE Setup.lhs _darcs dist haq.cabal<br />
</code><br />
<br />
which will fill out some stub Cabal files for the project 'haq'. <br />
<br />
To create an entirely new project tree:<br />
<br />
<code><br />
$ mkcabal --init-project<br />
Project name: haq<br />
What license ["GPL","LGPL","BSD3","BSD4","PublicDomain","AllRightsReserved"] ["BSD3"]: <br />
What kind of project [Executable,Library] [Executable]: <br />
Is this your name? - "Don Stewart " [Y/n]: <br />
Is this your email address? - "<dons@cse.unsw.edu.au>" [Y/n]: <br />
Created new project directory: haq<br />
$ cd haq<br />
$ ls<br />
Haq.hs LICENSE README Setup.lhs haq.cabal<br />
</code><br />
<br />
== Licenses ==<br />
<br />
Code for the common base library package must be BSD licensed. Otherwise, it<br />
is entirely up to you as the author.<br />
Choose a licence (inspired by [http://www.dina.dk/~abraham/rants/license.html this]).<br />
Check the licences of things you use (both other Haskell packages and C<br />
libraries), since these may impose conditions you must follow.<br />
Use the same licence as related projects, where possible. The Haskell community is<br />
split into 2 camps, roughly: those who release everything under BSD, and<br />
(L)GPLers. Some Haskellers recommend avoiding LGPL, due to cross-module optimisation<br />
issues. Like many licensing questions, this advice is controversial. Several Haskell projects<br />
(wxHaskell, HaXml, etc) use the LGPL with an extra permissive clause which gets round the<br />
cross-module optimisation problem.<br />
<br />
== Releases ==<br />
<br />
It's important to release your code as stable, tagged tarballs. Don't<br />
just [http://awayrepl.blogspot.com/2006/11/we-dont-do-releases.html rely on darcs for distribution].<br />
<br />
* '''darcs dist''' generates tarballs directly from a darcs repository<br />
<br />
For example:<br />
<br />
$ cd fps<br />
$ ls <br />
Data LICENSE README Setup.hs TODO _darcs cbits dist fps.cabal tests<br />
$ darcs dist -d fps-0.8<br />
Created dist as fps-0.8.tar.gz<br />
<br />
You can now just post your fps-0.8.tar.gz<br />
<br />
You can also have darcs do the equivalent of 'daily snapshots' for you by using a post-hook.<br />
<br />
put the following in _darcs/prefs/defaults:<br />
apply posthook darcs dist<br />
apply run-posthook<br />
<br />
Advice:<br />
* Tag each release using '''darcs tag'''. For example:<br />
<br />
$ darcs tag 0.8<br />
Finished tagging patch 'TAG 0.8'<br />
<br />
Then people can <tt>darcs pull --partial -t 0.8</tt>, to get just the tagged version (and not the entire history).<br />
<br />
== Hosting ==<br />
<br />
Hosting for repos is available from the Haskell community server:<br />
<br />
http://community.haskell.org/<br />
<br />
A Darcs repository can be published simply by making it available from a<br />
web page.<br />
<br />
== Web page ==<br />
<br />
Create a web page documenting your project! An easy way to do this is to<br />
add a project specific page to [[Haskell|the Haskell wiki]]<br />
<br />
== The user experience ==<br />
<br />
When developing a new Haskell library, it is important to remember how the user expects to be able to build and use a library.<br />
<br />
=== Introductory information and build guide ===<br />
<br />
A typical library user expects to:<br />
<br />
# Visit [[Haskell|Haskell.org]]<br />
# Find the library/program they are looking for:<br />
## if not found, try mailing list; <br />
## if it is hidden, try improving the documentation on haskell.org;<br />
## if it does not exist, try contributing code and documentation) <br />
# Download<br />
# Build and install<br />
# Enjoy<br />
<br />
Each of these steps can pose potential road blocks, and code authors can<br />
do a lot to help code users avoid such blocks. Steps 1..2 may be easy enough, and many coders and users are mainly concerned with step 5. Steps 3..4 are the ones that often get in the way. In particular, the<br />
following questions should have clear answers:<br />
<br />
* Which is the latest version? <br />
* What state is it in? <br />
* What are its aims? <br />
* Where is the documentation?<br />
* Which is the right version for given OS and Haskell implementation?<br />
* How is it packaged, and what tools are needed to get and unpack it?<br />
* How is it installed, and what tools are needed to install it?<br />
* How do we handle dependencies?<br />
* How do we provide/acquire the knowledge and tool-chains needed?<br />
<br />
The best place to answer these questions is a README file,<br />
distributed with the library or application, and often accompanied with<br />
similar text on a more extensive web page.<br />
<br />
=== Tutorials ===<br />
<br />
Generated haddock documentation is usually not enough to help new<br />
programmers learn how to use a library. You must also provide accompanying examples, and even tutorials about the library.<br />
<br />
Please consider providing example code for your library or application. The code should be type-correct and well-commented.<br />
<br />
== Program structure ==<br />
<br />
Monad transformers are very useful for programming in the large,<br />
encapsulating state, and controlling side effects. To learn more about this approach, try [http://uebb.cs.tu-berlin.de/~magr/pub/Transformers.en.html Monad Transformers Step by Step].<br />
<br />
== Publicity ==<br />
<br />
The best code in the world is meaningless if nobody knows about it. The<br />
process to follow once you've tagged and released your code is:<br />
<br />
=== Join the community ===<br />
<br />
If you haven't already, join the community. The best way to do this is to [http://haskell.org/haskellwiki/Mailing_lists subscribe] to at least haskell-cafe@ and haskell@ mailing lists. Joining the [[IRC_channel|#haskell IRC channel]] is also an excellent idea.<br />
<br />
=== Announce your project on haskell@ ===<br />
<br />
Most important: announce your project releases to the haskell@haskell.org mailing list. Tag your email subject line with "ANNOUNCE: ...". This ensure it will then make it into the [http://haskell.org/haskellwiki/HWN Haskell Weekly News]. To be doubly sure, you can email the release text to the [[HWN|HWN editor]].<br />
<br />
=== Add your code to the public collections ===<br />
<br />
* Add your library or application to the [[Libraries and tools]] page, under the relevant category, so people can find it.<br />
<br />
* If your release is a Cabal package, add it to the [http://hackage.haskell.org/packages/hackage.html Hackage database] (Haskell's CPAN wanna-be).<br />
<br />
=== Blog about it ===<br />
<br />
Blog about it! Blog about your new code on [http://planet.haskell.org Planet Haskell].<br />
Write about your project in your blog, then email the [http://planet.haskell.org/ Planet Haskell] maintainer (ibid on [[IRC channel|#haskell]]) the RSS feed url for your blog<br />
<br />
== Example ==<br />
<br />
[http://www.cse.unsw.edu.au/~dons/blog/2006/12/11#release-a-library-today A complete example] of writing, packaging and releasing a new Haskell library under this process has been documented.<br />
<br />
[[Category:Community]]<br />
[[Category:Tutorials]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Quasiquotation&diff=21904Quasiquotation2008-07-22T22:04:07Z<p>Heisenbug: another typo</p>
<hr />
<div>This is a tutorial for the quasiquoting facility described in<br />
[http://www.eecs.harvard.edu/~mainland/ghc-quasiquoting/mainland07quasiquoting.pdf Why It's Nice to be Quoted: Quasiquoting for Haskell]. Note that the syntax for<br />
quasiquotation has changed since the paper was written: now one writes<br />
<hask>[$expr|...|]</hask> instead of <hask>[:expr|...|]</hask>. Quasiquotation<br />
appeared in GHC 6.9 and is enabled with the <code>QuasiQuotes</code> language<br />
option (<code>-XQuasiQuotes</code> on the command line or <hask>{-# LANGUAGE QuasiQuotes #-}</hask> in a source file).<br />
<br />
We show how to build a quasiquoter for a simple mathematical expression<br />
language. Although the example is small, it demonstrates all aspects of building<br />
a quasiquoter. We do not mean to suggest that one gains much from a quasiquoter<br />
for such a small language relative to using abstract syntax directly except from<br />
a pedagogical point of view---this is just a tutorial!<br />
<br />
The tutorial is runnable if its contents is placed in files as follows:<br />
<br />
Place the contents of the [[#Syntax]] section in the file <code>Expr.hs</code><br />
with header<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveDataTypeable #-}<br />
module Expr (Expr(..),<br />
BinOp(..),<br />
eval,<br />
parseExpr)<br />
where<br />
<br />
import Data.Generics<br />
import Text.ParserCombinators.Parsec<br />
</haskell><br />
<br />
Place the contents of the section [[#Parsing]] and [[#The Quasiquoter]] in a<br />
file <code>Expr/Quote.hs</code> with header<br />
<br />
<haskell><br />
module Expr.Quote (expr) where<br />
<br />
import Data.Generics<br />
import qualified Language.Haskell.TH as TH<br />
import Language.Haskell.TH.Quote<br />
<br />
import Expr<br />
</haskell><br />
<br />
= Syntax =<br />
<br />
Our simple expression language consists of integers, the standard operators<br />
+,x,*,/, and parenthesized expressions. We will write a single parser that takes<br />
concrete syntax for this language and transforms it to abstract syntax. Using<br />
the SYB approach to generic programming, we will then use this parser to produce<br />
expression and pattern quasiquoters. Our quasiquoter will allow us to write<br />
<hask>[$expr|1 + 3|]</hask> directly in Haskell source code instead of the<br />
corresponding abstract syntax.<br />
<br />
An obvious datatype for the abstract syntax of this simple language is:<br />
<br />
<haskell><br />
data Expr = IntExpr Integer<br />
| BinopExpr (Integer -> Integer -> Integer) Expr Expr<br />
deriving(Show)<br />
</haskell><br />
<br />
Unfortunately, this won't do for our quasiquoter. First of all, the SYB<br />
technique we use cannot handle function types in a generic way, so the BinopExpr<br />
constructor must be modified. SYB also requires that we derive Typeable and<br />
Data, a trivial change. Finally, we want to support antiquoting fro two<br />
syntactic categories, expressions and integers. With antiquoting support, we can<br />
write [$expr|$x + $int:y|] where x and y are in-scope variables with types Expr<br />
and Integer, respectively. The final data types for our abstract syntax are:<br />
<br />
<haskell><br />
data Expr = IntExpr Integer<br />
| AntiIntExpr String<br />
| BinopExpr BinOp Expr Expr<br />
| AntiExpr String<br />
deriving(Show, Typeable, Data)<br />
<br />
data BinOp = AddOp<br />
| SubOp<br />
| MulOp<br />
| DivOp<br />
deriving(Show, Typeable, Data)<br />
</haskell><br />
<br />
An evaluator for out abstract syntax can be written as follows:<br />
<br />
<haskell><br />
eval :: Expr -> Integer<br />
eval (IntExpr n) = n<br />
eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)<br />
where<br />
opToFun AddOp = (+)<br />
opToFun SubOp = (-)<br />
opToFun MulOp = (*)<br />
opToFun DivOp = div<br />
</haskell><br />
<br />
= Parsing =<br />
<br />
We use Parsec to write a parser for our expression language. Note that we have<br />
(somewhat arbitrarily) chosen the syntax for antiquotaton to be as in the above<br />
example; a quasiquoter may choose whatever syntax she wishes.<br />
<br />
<haskell><br />
small = lower <|> char '_'<br />
large = upper<br />
idchar = small <|> large <|> digit <|> char '\''<br />
<br />
lexeme p = do{ x <- p; spaces; return x }<br />
symbol name = lexeme (string name)<br />
parens p = between (symbol "(") (symbol ")") p<br />
<br />
expr :: CharParser st Expr<br />
expr = term `chainl1` addop<br />
<br />
term :: CharParser st Expr<br />
term = factor `chainl1` mulop<br />
<br />
factor :: CharParser st Expr<br />
factor = parens expr <|> integer <|> try antiIntExpr <|> antiExpr<br />
<br />
mulop = do{ symbol "*"; return $ BinopExpr MulOp }<br />
<|> do{ symbol "/"; return $ BinopExpr DivOp }<br />
<br />
addop = do{ symbol "+"; return $ BinopExpr AddOp }<br />
<|> do{ symbol "-"; return $ BinopExpr SubOp }<br />
<br />
integer :: CharParser st Expr<br />
integer = lexeme $ do{ ds <- many1 digit ; return $ IntExpr (read ds) }<br />
<br />
ident :: CharParser s String<br />
ident = do{ c <- small; cs <- many idchar; return (c:cs) }<br />
<br />
antiIntExpr = lexeme $ do{ symbol "$int:"; id <- ident; return $ AntiIntExpr id }<br />
antiExpr = lexeme $ do{ symbol "$"; id <- ident; return $ AntiExpr id }<br />
</haskell><br />
<br />
The helper function parseExpr takes a source code position (consisting of a file<br />
name, line and column) and a string and returns a value of type Expr. This<br />
helper function also ensures that we can parse the whole string rather than just<br />
a prefix.<br />
<br />
<haskell><br />
parseExpr :: Monad m => (String, Int, Int) -> String -> m Expr<br />
parseExpr (file, line, col) s =<br />
case runParser p () "" s of<br />
Left err -> fail $ show err<br />
Right e -> return e<br />
where<br />
p = do pos <- getPosition<br />
setPosition $<br />
(flip setSourceName) file $<br />
(flip setSourceLine) line $<br />
(flip setSourceColumn) col $<br />
pos<br />
spaces<br />
e <- expr<br />
eof<br />
return e<br />
</haskell><br />
<br />
= The Quasiquoter =<br />
<br />
Remember, our quasiquoter allows us to write expression in our simple language,<br />
such as [$expr|2 * 3|], directly in Haskell source code. This requires that the<br />
variable expr be in-scope when the quasiquote is encountered, and that it is<br />
bound to a value of type Language.Haskell.TH.Quote.QuasiQuoter, which contains<br />
an expression quoter and a pattern quoter. Note that expr must obey the same<br />
stage restrictions as Template Haskell; in particular, it may not be defined in<br />
the same module where it is used as a quasiquoter, but must be imported.<br />
<br />
Our expression and pattern quoters are quoteExprExp and quoteExprPat,<br />
respectively, so our quasiquoter expr is written as follows:<br />
<br />
<haskell><br />
quoteExprExp :: String -> TH.ExpQ<br />
quoteExprPat :: String -> TH.PatQ<br />
<br />
expr :: QuasiQuoter<br />
expr = QuasiQuoter quoteExprExp quoteExprPat<br />
</haskell><br />
<br />
Our quasiquoters re-use the parser we wrote in the previous section, parseExpr,<br />
and make use of the generic functions dataToExpQ and dataToPatQ (described in<br />
the Haskell Workshop paper). These functions, from the Language.Haskell.TH.Quote<br />
package, take a Haskell value and reflect it back into the language as Template<br />
Haskell abstract syntax. The catch is that we don't want to handle all values<br />
generically: antiquoted values must be handled specially. Consider the AntiExpr<br />
constructor; we don't want this constructor to be mapped to Template Haskell<br />
abstract syntax for the AntiExpr constructor, but to abstract syntax for the<br />
Haskell variable named by the constructor's argument. The extQ combinator allows<br />
us to do this nicely by defining a function antiExprExp that handles<br />
antiquotations.<br />
<br />
<haskell><br />
quoteExprExp s = do loc <- TH.location<br />
let pos = (TH.loc_filename loc,<br />
fst (TH.loc_start loc),<br />
snd (TH.loc_start loc))<br />
expr <- parseExpr pos s<br />
dataToExpQ (const Nothing `extQ` antiExprExp) expr<br />
<br />
antiExprExp :: Expr -> Maybe (TH.Q TH.Exp)<br />
antiExprExp (AntiIntExpr v) = Just $ TH.appE (TH.conE (TH.mkName "IntExpr"))<br />
(TH.varE (TH.mkName v))<br />
antiExprExp (AntiExpr v) = Just $ TH.varE (TH.mkName v)<br />
antiExprExp _ = Nothing<br />
</haskell><br />
<br />
The corresponding code for patterns is:<br />
<br />
<haskell><br />
quoteExprPat s = do loc <- TH.location<br />
let pos = (TH.loc_filename loc,<br />
fst (TH.loc_start loc),<br />
snd (TH.loc_start loc))<br />
expr <- parseExpr pos s<br />
dataToPatQ (const Nothing `extQ` antiExprPat) expr<br />
<br />
antiExprPat :: Expr -> Maybe (TH.Q TH.Pat)<br />
antiExprPat (AntiIntExpr v) = Just $ TH.conP (TH.mkName "IntExpr")<br />
[TH.varP (TH.mkName v)]<br />
antiExprPat (AntiExpr v) = Just $ TH.varP (TH.mkName v)<br />
antiExprPat _ = Nothing<br />
</haskell><br />
<br />
= Examples =<br />
<br />
We can now try out a few examples by invoking ghci as follows: <code>ghci -XQuasiQuotes Expr/Quote</code><br />
<br />
<pre><br />
> [$expr|1 + 3 + 5|]<br />
BinopExpr AddOp (BinopExpr AddOp (IntExpr 1) (IntExpr 3)) (IntExpr 5) <br />
> eval [$expr|1 + 3 + 5|]<br />
9 <br />
</pre><br />
<br />
Taking advantage of our quasiquoter, we can re-write our evaluator so it uses<br />
concrete syntax:<br />
<br />
<haskell><br />
eval' :: Expr -> Integer<br />
eval' [$expr|$int:x|] = x<br />
eval' [$expr|$x + $y|] = eval' x + eval' y<br />
eval' [$expr|$x - $y|] = eval' x - eval' y<br />
eval' [$expr|$x * $y|] = eval' x * eval' y<br />
eval' [$expr|$x / $y|] = eval' x `div` eval' y<br />
</haskell><br />
<br />
Let's make sure it works as advertised:<br />
<br />
<pre><br />
> eval [$expr|1 + 2 + 3|] == eval' [$expr|1 + 2 + 3|]<br />
True <br />
> eval [$expr|1 + 3 * 5|] == eval' [$expr|1 + 3 * 5|]<br />
True <br />
</pre></div>Heisenbughttps://wiki.haskell.org/index.php?title=Quasiquotation&diff=21903Quasiquotation2008-07-22T22:02:54Z<p>Heisenbug: correct a typo</p>
<hr />
<div>This is a tutorial for the quasiquoting facility described in<br />
[http://www.eecs.harvard.edu/~mainland/ghc-quasiquoting/mainland07quasiquoting.pdf Why It's Nice to be Quoted: Quasiquoting for Haskell]. Note that the syntax for<br />
quasiquotation has changed since the paper was written: now one writes<br />
<hask>[$expr|...|]</hask> instead of <hask>[:expr|...|]</hask>. Quasiquotation<br />
appeared in GHC 6.9 and is enabled with the <code>QuasiQuotes</code> language<br />
option (<code>-XQuasiQuotes</code> on the command line or <hask>{-# LANGUAGE QuasiQuotes #-}</hask> in a source file).<br />
<br />
We show how to build a quasiquoter for a simple mathematical expression<br />
language. Although the example is small, it demonstrates all aspects of building<br />
a quasioquter. We do not mean to suggest that one gains much from a quasiquoter<br />
for such a small language relative to using abstract syntax directly except from<br />
a pedagogical point of view---this is just a tutorial!<br />
<br />
The tutorial is runnable if its contents is placed in files as follows:<br />
<br />
Place the contents of the [[#Syntax]] section in the file <code>Expr.hs</code><br />
with header<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveDataTypeable #-}<br />
module Expr (Expr(..),<br />
BinOp(..),<br />
eval,<br />
parseExpr)<br />
where<br />
<br />
import Data.Generics<br />
import Text.ParserCombinators.Parsec<br />
</haskell><br />
<br />
Place the contents of the section [[#Parsing]] and [[#The Quasiquoter]] in a<br />
file <code>Expr/Quote.hs</code> with header<br />
<br />
<haskell><br />
module Expr.Quote (expr) where<br />
<br />
import Data.Generics<br />
import qualified Language.Haskell.TH as TH<br />
import Language.Haskell.TH.Quote<br />
<br />
import Expr<br />
</haskell><br />
<br />
= Syntax =<br />
<br />
Our simple expression language consists of integers, the standard operators<br />
+,x,*,/, and parenthesized expressions. We will write a single parser that takes<br />
concrete syntax for this language and transforms it to abstract syntax. Using<br />
the SYB approach to generic programming, we will then use this parser to produce<br />
expression and pattern quasiquoters. Our quasiquoter will allow us to write<br />
<hask>[$expr|1 + 3|]</hask> directly in Haskell source code instead of the<br />
corresponding abstract syntax.<br />
<br />
An obvious datatype for the abstract syntax of this simple language is:<br />
<br />
<haskell><br />
data Expr = IntExpr Integer<br />
| BinopExpr (Integer -> Integer -> Integer) Expr Expr<br />
deriving(Show)<br />
</haskell><br />
<br />
Unfortunately, this won't do for our quasiquoter. First of all, the SYB<br />
technique we use cannot handle function types in a generic way, so the BinopExpr<br />
constructor must be modified. SYB also requires that we derive Typeable and<br />
Data, a trivial change. Finally, we want to support antiquoting fro two<br />
syntactic categories, expressions and integers. With antiquoting support, we can<br />
write [$expr|$x + $int:y|] where x and y are in-scope variables with types Expr<br />
and Integer, respectively. The final data types for our abstract syntax are:<br />
<br />
<haskell><br />
data Expr = IntExpr Integer<br />
| AntiIntExpr String<br />
| BinopExpr BinOp Expr Expr<br />
| AntiExpr String<br />
deriving(Show, Typeable, Data)<br />
<br />
data BinOp = AddOp<br />
| SubOp<br />
| MulOp<br />
| DivOp<br />
deriving(Show, Typeable, Data)<br />
</haskell><br />
<br />
An evaluator for out abstract syntax can be written as follows:<br />
<br />
<haskell><br />
eval :: Expr -> Integer<br />
eval (IntExpr n) = n<br />
eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)<br />
where<br />
opToFun AddOp = (+)<br />
opToFun SubOp = (-)<br />
opToFun MulOp = (*)<br />
opToFun DivOp = div<br />
</haskell><br />
<br />
= Parsing =<br />
<br />
We use Parsec to write a parser for our expression language. Note that we have<br />
(somewhat arbitrarily) chosen the syntax for antiquotaton to be as in the above<br />
example; a quasiquoter may choose whatever syntax she wishes.<br />
<br />
<haskell><br />
small = lower <|> char '_'<br />
large = upper<br />
idchar = small <|> large <|> digit <|> char '\''<br />
<br />
lexeme p = do{ x <- p; spaces; return x }<br />
symbol name = lexeme (string name)<br />
parens p = between (symbol "(") (symbol ")") p<br />
<br />
expr :: CharParser st Expr<br />
expr = term `chainl1` addop<br />
<br />
term :: CharParser st Expr<br />
term = factor `chainl1` mulop<br />
<br />
factor :: CharParser st Expr<br />
factor = parens expr <|> integer <|> try antiIntExpr <|> antiExpr<br />
<br />
mulop = do{ symbol "*"; return $ BinopExpr MulOp }<br />
<|> do{ symbol "/"; return $ BinopExpr DivOp }<br />
<br />
addop = do{ symbol "+"; return $ BinopExpr AddOp }<br />
<|> do{ symbol "-"; return $ BinopExpr SubOp }<br />
<br />
integer :: CharParser st Expr<br />
integer = lexeme $ do{ ds <- many1 digit ; return $ IntExpr (read ds) }<br />
<br />
ident :: CharParser s String<br />
ident = do{ c <- small; cs <- many idchar; return (c:cs) }<br />
<br />
antiIntExpr = lexeme $ do{ symbol "$int:"; id <- ident; return $ AntiIntExpr id }<br />
antiExpr = lexeme $ do{ symbol "$"; id <- ident; return $ AntiExpr id }<br />
</haskell><br />
<br />
The helper function parseExpr takes a source code position (consisting of a file<br />
name, line and column) and a string and returns a value of type Expr. This<br />
helper function also ensures that we can parse the whole string rather than just<br />
a prefix.<br />
<br />
<haskell><br />
parseExpr :: Monad m => (String, Int, Int) -> String -> m Expr<br />
parseExpr (file, line, col) s =<br />
case runParser p () "" s of<br />
Left err -> fail $ show err<br />
Right e -> return e<br />
where<br />
p = do pos <- getPosition<br />
setPosition $<br />
(flip setSourceName) file $<br />
(flip setSourceLine) line $<br />
(flip setSourceColumn) col $<br />
pos<br />
spaces<br />
e <- expr<br />
eof<br />
return e<br />
</haskell><br />
<br />
= The Quasiquoter =<br />
<br />
Remember, our quasiquoter allows us to write expression in our simple language,<br />
such as [$expr|2 * 3|], directly in Haskell source code. This requires that the<br />
variable expr be in-scope when the quasiquote is encountered, and that it is<br />
bound to a value of type Language.Haskell.TH.Quote.QuasiQuoter, which contains<br />
an expression quoter and a pattern quoter. Note that expr must obey the same<br />
stage restrictions as Template Haskell; in particular, it may not be defined in<br />
the same module where it is used as a quasiquoter, but must be imported.<br />
<br />
Our expression and pattern quoters are quoteExprExp and quoteExprPat,<br />
respectively, so our quasiquoter expr is written as follows:<br />
<br />
<haskell><br />
quoteExprExp :: String -> TH.ExpQ<br />
quoteExprPat :: String -> TH.PatQ<br />
<br />
expr :: QuasiQuoter<br />
expr = QuasiQuoter quoteExprExp quoteExprPat<br />
</haskell><br />
<br />
Our quasiquoters re-use the parser we wrote in the previous section, parseExpr,<br />
and make use of the generic functions dataToExpQ and dataToPatQ (described in<br />
the Haskell Workshop paper). These functions, from the Language.Haskell.TH.Quote<br />
package, take a Haskell value and reflect it back into the language as Template<br />
Haskell abstract syntax. The catch is that we don't want to handle all values<br />
generically: antiquoted values must be handled specially. Consider the AntiExpr<br />
constructor; we don't want this constructor to be mapped to Template Haskell<br />
abstract syntax for the AntiExpr constructor, but to abstract syntax for the<br />
Haskell variable named by the constructor's argument. The extQ combinator allows<br />
us to do this nicely by defining a function antiExprExp that handles<br />
antiquotations.<br />
<br />
<haskell><br />
quoteExprExp s = do loc <- TH.location<br />
let pos = (TH.loc_filename loc,<br />
fst (TH.loc_start loc),<br />
snd (TH.loc_start loc))<br />
expr <- parseExpr pos s<br />
dataToExpQ (const Nothing `extQ` antiExprExp) expr<br />
<br />
antiExprExp :: Expr -> Maybe (TH.Q TH.Exp)<br />
antiExprExp (AntiIntExpr v) = Just $ TH.appE (TH.conE (TH.mkName "IntExpr"))<br />
(TH.varE (TH.mkName v))<br />
antiExprExp (AntiExpr v) = Just $ TH.varE (TH.mkName v)<br />
antiExprExp _ = Nothing<br />
</haskell><br />
<br />
The corresponding code for patterns is:<br />
<br />
<haskell><br />
quoteExprPat s = do loc <- TH.location<br />
let pos = (TH.loc_filename loc,<br />
fst (TH.loc_start loc),<br />
snd (TH.loc_start loc))<br />
expr <- parseExpr pos s<br />
dataToPatQ (const Nothing `extQ` antiExprPat) expr<br />
<br />
antiExprPat :: Expr -> Maybe (TH.Q TH.Pat)<br />
antiExprPat (AntiIntExpr v) = Just $ TH.conP (TH.mkName "IntExpr")<br />
[TH.varP (TH.mkName v)]<br />
antiExprPat (AntiExpr v) = Just $ TH.varP (TH.mkName v)<br />
antiExprPat _ = Nothing<br />
</haskell><br />
<br />
= Examples =<br />
<br />
We can now try out a few examples by invoking ghci as follows: <code>ghci -XQuasiQuotes Expr/Quote</code><br />
<br />
<pre><br />
> [$expr|1 + 3 + 5|]<br />
BinopExpr AddOp (BinopExpr AddOp (IntExpr 1) (IntExpr 3)) (IntExpr 5) <br />
> eval [$expr|1 + 3 + 5|]<br />
9 <br />
</pre><br />
<br />
Taking advantage of our quasiquoter, we can re-write our evaluator so it uses<br />
concrete syntax:<br />
<br />
<haskell><br />
eval' :: Expr -> Integer<br />
eval' [$expr|$int:x|] = x<br />
eval' [$expr|$x + $y|] = eval' x + eval' y<br />
eval' [$expr|$x - $y|] = eval' x - eval' y<br />
eval' [$expr|$x * $y|] = eval' x * eval' y<br />
eval' [$expr|$x / $y|] = eval' x `div` eval' y<br />
</haskell><br />
<br />
Let's make sure it works as advertised:<br />
<br />
<pre><br />
> eval [$expr|1 + 2 + 3|] == eval' [$expr|1 + 2 + 3|]<br />
True <br />
> eval [$expr|1 + 3 * 5|] == eval' [$expr|1 + 3 * 5|]<br />
True <br />
</pre></div>Heisenbughttps://wiki.haskell.org/index.php?title=Template:Main/News&diff=14691Template:Main/News2007-07-25T21:30:03Z<p>Heisenbug: typo</p>
<hr />
<div>''2007-07-23''<br />
<br />
<ul><li><p><em>Learn Haskell in 10 minutes</em>. Chris Smith<br />
[http://haskell.org/haskellwiki/Learn_Haskell_in_10_minutes prepared] a new tutorial on the basics of Haskell</p></li><br />
<br />
<li><p><em>Haskell Program Coverage 0.4</em>. Andy Gill<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15381 announced] release 0.4 of Hpc, a tool for Haskell developers. Hpc is a tool-kit to record and display Haskell Program Coverage. Hpc includes tools that instrument Haskell programs to record program coverage, run instrumented programs, and display the coverage information obtained.</p></li><br />
<br />
<li><p><em>Uniplate 1.0</em>. Neil Mitchell<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15366 announced] Uniplate (formerly known as Play), a library for boilerplate removal requiring only Haskell 98 (for normal use) and optionally multi-parameter type classes (for more advanced features).</p></li><br />
<br />
<li><p><em>Atom: Hardware description in Haskell</em>. Tom Hawkins <br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15341 announced] Atom, a high-level hardware description language embedded in Haskell that compiles conditional term rewriting systems into conventional HDL.</p></li><br />
<br />
<li><p><em>Catch</em>. Neil Mitchell<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15334 announced] a pattern-match checker for Haskell, named Catch. Do you sometimes encounter the dreaded 'pattern match failure: head' message? Do you have incomplete patterns which sometimes fail? Do you have incomplete patterns which you know don't fail, but still get compiler warnings about them? Would you like to statically ensure the absence of all calls to error? This is what Catch helps ... catch!</p></li><br />
<br />
<li><p><em>Haskell Communities and Activities Report</em>. Andres Loeh <br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15302 announced] that the Haskell Communities and Activities Report is now available, covering the increasingly diverse groups, projects and individuals working on, with, or inspired by Haskell.</p></li><br />
<br />
<li><p><em>The Reduceron</em>. Matthew Naylor<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15301 announced] the Reduceron, a processor for executing Haskell programs on FPGA with the aim of exploring how custom architectural features can improve the speed in which Haskell functions are evaluated. Being described entirely in Haskell (using Lava), the Reduceron also serves as an interesting application of functional languages to the design of complex control circuits such as processors.</p></li><br />
<br />
<li><p><em>Data.Derive</em>. Neil Mitchell<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15292 announced] Data.Derive, a library and a tool for deriving instances for Haskell programs. It is designed to work with custom derivations, SYB and Template Haskell mechanisms. The tool requires GHC, but the generated code is portable to all compilers. We see this tool as a competitor to DrIFT.</p></li><br />
<br />
<li><p><em>Piffle, a packet filter language</em>. Jaap Weel<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15290 announced] Piffle, a compiler for a packet filter language in Haskell: a good example of how Haskell can be used in an application domain (low level computer networking) where people tend to use C for everything, including writing compilers.</p></li><br />
<br />
<li><p><em>Towards a Programming Language Nirvana</em>. Simon Peyton-Jones<br />
[http://channel9.msdn.com/showpost.aspx?postid=326762 appears] on video, talking about the Haskell path to programming language Nirvana</p></li><br />
<br />
<li><p><em>Yi 0.2</em>. Jean-Philippe Bernardy<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15260 announced] the 0.2.0 release of the Yi editor. Yi is a text editor written and extensible in Haskell. The goal of Yi is to provide a flexible, powerful and correct editor core dynamically scriptable in Haskell. Yi is also a Haskell interpreter, very much like emacs is a Lisp interpreter, this makes really easy to dynamically hack, experiment and modify Yi. All tools and goodies written in haskell are also readily available from the editor. This is implemented by binding to the GHC API.</p></li><br />
<br />
<li><p><em>Foreign.AppleScript</em>. Wouter Swierstra<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15246 announced] a library for compiling and executing AppleScript from Haskell. AppleScript is a scripting language available on all modern Apple computers. It can be used to script most applications on running on MacOS X.</p></li><br />
<br />
<li><p><em>Asterisk Gateway Interface</em>. Jeremy Shaw<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15245 uploaded] a simple AGI interface to [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/AGI hackage]. For more about Asterix, see [http://www.voip-info.org/wiki-Asterisk+AGI here].</p></li><br />
<br />
<li><p><em>Harpy</em>. Dirk Kleeblatt<br />
[http://article.gmane.org/gmane.comp.lang.haskell.general/15237 announced] Harpy, a library for run-time code generation of x86 machine code. It provides not only a low level interface to code generation operations, but also a convenient domain specific language for machine code fragments, a collection of code generation combinators and a disassembler. [http://haskell.org/haskellwiki/Blog_articles/EDSLs Lennart Augustsson] has written a series of articles demonstrating its use for fast EDSLs.</p></li><br />
<br />
<li><p><em>Yaml Reference</em>. Gaal Yahas<br />
[http://ben-kiki.org/oren/YamlReference/ announced] a Haskell (Cabal) package containing the YAML spec productions wrapped in Haskell magic to convert them to an executable parser. The parser is streaming. It isn't intended to serve as a basis for a YAML tool chain; instead it is meant to serve as a reference implementation of the spec.</p></li></ul><br />
<br />
[[Old news|More news]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Template:Main/Events&diff=14157Template:Main/Events2007-07-11T00:28:04Z<p>Heisenbug: HaL2 is over</p>
<hr />
<div>{| border="0" cellspacing="0" cellpadding="2"<br />
! <br />
!<br />
!<br />
|-<br />
| [http://www.icfpcontest.org/ ICFP Programming Contest 2007]<br />
| [http://haskell.org/haskellwiki/ICFP_Programming_Contest/Teams_2007 Anywhere]<br />
| July 20-23, 2007<br />
|-<br />
| [http://conferences.oreillynet.com/cs/os2007/view/e_sess/14016 OSCON Haskell Tutorial]<br />
| Portland/Oregon<br />
| July 23, 2007<br />
|-<br />
| [http://f.loulergue.free.fr/HLPP/hlpp2007/ High-level Parallel Programming Workshop]<br />
| Tokyo/Japan<br />
| July 23-24, 2007<br />
|-<br />
| [http://proglang.informatik.uni-freiburg.de/IFL2007/ IFL]<br />
| Freiburg/Germany<br />
| September 27-29, 2007<br />
|-<br />
| [http://www.cse.unsw.edu.au/~keller/haskellws/HaskellWorkshop.html Haskell Workshop]<br />
| Freiburg/Germany<br />
| September 30, 2007<br />
|-<br />
| [http://www.informatik.uni-bonn.de/~ralf/icfp07.html ICFP]<br />
| Freiburg/Germany<br />
| October 1-3 2007<br />
|-<br />
| [http://www.haskell.org/haskellwiki/Hac_2007_II Hackathon]<br />
| Freiburg/Germany<br />
| Sept/October 2007<br />
|-<br />
| [http://www.cs.uu.nl/~johanj/FPDag2008/ FPDag]<br />
| Utrecht/Netherlands<br />
| January 11, 2008<br />
|-<br />
|}<br />
<br />
[[Category:Events]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Pt/Haskell&diff=13387Pt/Haskell2007-06-04T21:55:14Z<p>Heisenbug: mais um</p>
<hr />
<div><p style="text-align:center"><br />
Haskell é uma linguagem de propósito geral, linguagem de programação puramente funcional e fortemente tipada, com funções de alta ordem, polimorfismo, classes tipadas e mônadas. Compiladores Haskell são livremente disponíveis para as mais variadas plataformas.<br />
</p><br />
<br />
__NOTOC__<br />
{| border=0 cellspacing=5 cellpadding=15<br />
| valign=top bgcolor=#F0F0F0 style="text-align:left" |<br />
== Sobre ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Introdução]]<br />
|-<br />
| [[Linguagem e especificação das bibliotecas|Definição da Linguagem]]<br />
|-<br />
| [[História do Haskell|História]]<br />
|-<br />
| [[Futuro]]<br />
|-<br />
| [[Implementação]]<br />
|-<br />
|}<br />
: [http://haskell.org/ghc GHC]<br />
: [http://haskell.org/hugs Hugs]<br />
: [http://haskell.org/nhc98 nhc98]<br />
: [[Yhc]]<br />
<br />
== Como começar ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Haskell em 5 passos]]<br />
|-<br />
| [[Aprendendo Haskell]]<br />
|-<br />
| [[Livros e tutoriais]]<br />
|-<br />
| [[:Categoria:Haskell|Artigos Wiki]]<br />
|-<br />
| [[Blog artigos]]<br />
|-<br />
| [http://en.wikibooks.org/wiki/Haskell Wikibook]<br />
|-<br />
| [[Research papers]]<br />
|-<br />
| [[Códigos exemplo]] <br />
|-<br />
|}<br />
<br />
== Bibliotecas ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [http://haskell.org/ghc/docs/latest/html/libraries/ Bibliotecas padrão]<br />
|-<br />
| [http://hackage.haskell.org Banco de dados de bibliotecas Hackage]<br />
|-<br />
| [[Libraries and tools|Aplicações e bibliotecas]]<br />
|-<br />
| [http://haskell.org/hoogle Hoogle: procura de bibliotecas]<br />
|-<br />
|}<br />
<br />
<br />
<br />
== Comunidade ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [http://haskell.org/communities/ Comunidades de projetos]<br />
|}<br />
: [[Haskell_in_education|Educação]]<br />
: [[Haskell in industry|Indústria]]<br />
: [[Haskell_in_research|Pesquisa]]<br />
: [[Haskell_and_mathematics|Matemática]]<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Mailing lists]]<br />
|-<br />
| [[IRC channel]]<br />
|-<br />
| [[User groups]]<br />
|-<br />
| [http://planet.haskell.org/ Planet Haskell]<br />
|-<br />
| [[Haskell Notícias semanais]]<br />
|-<br />
| [http://sequence.complete.org The Haskell Sequence]<br />
|-<br />
| [http://hpaste.org/ Haskell pastebin]<br />
|-<br />
| [[Conferências]]<br />
|-<br />
| [[Programming contests|Conteúdo]]<br />
|-<br />
| [[Trabalhos]]<br />
|-<br />
| [[Consultores]]<br />
|-<br />
| [[Humor]]<br />
|-<br />
| [[Merchandise]]<br />
|-<br />
| [[Haskell.org|haskell.org]]<br />
|-<br />
| [[HaskellWiki:Contributing|Contribuindo para o site]]<br />
|-<br />
| Languages: [[Haskell|en]] [[Es/Haskell|es]] [[Ro/Haskell|ro]] [[Pt/Haskell|pt]] [[Fr/Haskell|fr]] <br />
|-<br />
|}<br />
<br />
|valign=top bgcolor=#F0F0F0 width=65% style="text-align:left"|<br />
<br />
<br />
== Eventos ==<br />
{{:Events}}<br />
<br />
<br />
== Headlines ==<br />
<br />
* Haskell.org é a organização mentora no [http://code.google.com/soc 2007 Google Summer of Code]. 9 estudantes foram convidados pelo Google para trabalhar na infraestrutura do projeto para Haskell.<br />
<br />
* O comitê [http://hackage.haskell.org/trac/haskell-prime Haskell-prime] começou a trabalhar para definir a próxima ''minor revision'' da especificação da linguagem.<br />
<br />
* A comunidade Haskell [http://www.haskell.org/communities November 2006] Relatório de Atividades foi criada, documentando projetos para a comunidade Haskell.<br />
<br />
* Haskell, pelo terceiro ano seguido, foi usado por [http://googleresearch.blogspot.com/2006/09/and-awards-go-to.html the winning team] e no [http://www.boundvariable.org/scoreboard.shtml ICFP Programming Contest].<br />
<br />
<br />
== Livros-texto ==<br />
<br />
;[[Image:Uma_Abordagem_Pratica.jpg|Cover]] Claudio Cesar de S and Marcio Ferreira da Silva: <em> Haskell: Uma Abordagem Prática</em>, [http://www.novatec.com.br Novatec Editora Ltda.], 2006, 296 pages, ISBN 85-7522-095-0. The price is R$ 62,00 (in Reais). Language: Portugese<br />
<br />
<blockquote><br />
This book is being published by Novatec Editora Ltda. You can access directly [http://www.novateceditora.com.br/livros/haskell/ here].<br />
<br><br />
<b>Book description:</b><br><br />
This book brings a comprehensive vision of Haskell language. No <br />
knowledge in another functional programming language is expected. In <br />
addition, no background in programming is required. The book presents <br />
issues from basic up to an intermediate level; it also includes some <br />
advanced aspects of Haskell. The title of the book, <em>Haskell: Uma <br />
Abordagem Prática</em>, in English <em>Haskell: A Practical Approach</em>, is the essence of the book.<br />
The result is a text that can be used in courses of programming and paradigms languages.<br />
Finally, many practical examples can be found <br />
throughout the book.<br />
<br />
An additional page containing comments on this book is found here:<br />
[http://www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell].<br />
Other data as bibtex entry, cover's book in several formats, <br />
Winhugs-2001 for download, and so on. This page is Portugese.<br />
</blockquote><br />
<br />
<br />
== Notícias ==<br />
{{:News}}<br />
<br />
|}<br />
<br />
== Articles ==<br />
<br />
[[Category:Community]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Pt/Haskell&diff=13386Pt/Haskell2007-06-04T21:53:41Z<p>Heisenbug: typo in title</p>
<hr />
<div><p style="text-align:center"><br />
Haskell é uma linguagem de propósito geral, linguagem de programação puramente funcional e fortemente tipada, com funções de alta ordem, polimorfismo, classes tipadas e mônadas. Compiladores Haskell são livremente disponíveis para as mais variadas plataformas.<br />
</p><br />
<br />
__NOTOC__<br />
{| border=0 cellspacing=5 cellpadding=15<br />
| valign=top bgcolor=#F0F0F0 style="text-align:left" |<br />
== Sobre ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Introdução]]<br />
|-<br />
| [[Linguagem e especificação das bibliotecas|Definição da Linguagem]]<br />
|-<br />
| [[História do Haskell|História]]<br />
|-<br />
| [[Futuro]]<br />
|-<br />
| [[Implementação]]<br />
|-<br />
|}<br />
: [http://haskell.org/ghc GHC]<br />
: [http://haskell.org/hugs Hugs]<br />
: [http://haskell.org/nhc98 nhc98]<br />
: [[Yhc]]<br />
<br />
== Como começar ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Haskell em 5 passos]]<br />
|-<br />
| [[Aprendendo Haskell]]<br />
|-<br />
| [[Livros e tutoriais]]<br />
|-<br />
| [[:Categoria:Haskell|Artigos Wiki]]<br />
|-<br />
| [[Blog artigos]]<br />
|-<br />
| [http://en.wikibooks.org/wiki/Haskell Wikibook]<br />
|-<br />
| [[Research papers]]<br />
|-<br />
| [[Códigos exemplo]] <br />
|-<br />
|}<br />
<br />
== Bibliotecas ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [http://haskell.org/ghc/docs/latest/html/libraries/ Bibliotecas padrão]<br />
|-<br />
| [http://hackage.haskell.org Banco de dados de bibliotecas Hackage]<br />
|-<br />
| [[Libraries and tools|Aplicações e bibliotecas]]<br />
|-<br />
| [http://haskell.org/hoogle Hoogle: procura de bibliotecas]<br />
|-<br />
|}<br />
<br />
<br />
<br />
== Comunidade ==<br />
<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [http://haskell.org/communities/ Comunidades de projetos]<br />
|}<br />
: [[Haskell_in_education|Educação]]<br />
: [[Haskell in industry|Indústria]]<br />
: [[Haskell_in_research|Pesquisa]]<br />
: [[Haskell_and_mathematics|Matemática]]<br />
{| border="0" cellspacing="0" cellpadding="2" style="text-align:left"<br />
|-<br />
| [[Mailing lists]]<br />
|-<br />
| [[IRC channel]]<br />
|-<br />
| [[User groups]]<br />
|-<br />
| [http://planet.haskell.org/ Planet Haskell]<br />
|-<br />
| [[Haskell Notícias semanais]]<br />
|-<br />
| [http://sequence.complete.org The Haskell Sequence]<br />
|-<br />
| [http://hpaste.org/ Haskell pastebin]<br />
|-<br />
| [[Conferências]]<br />
|-<br />
| [[Programming contests|Conteúdo]]<br />
|-<br />
| [[Trabalhos]]<br />
|-<br />
| [[Consultores]]<br />
|-<br />
| [[Humor]]<br />
|-<br />
| [[Merchandise]]<br />
|-<br />
| [[Haskell.org|haskell.org]]<br />
|-<br />
| [[HaskellWiki:Contributing|Contribuindo para o site]]<br />
|-<br />
| Languages: [[Haskell|en]] [[Es/Haskell|es]] [[Ro/Haskell|ro]] [[Pt/Haskell|pt]] [[Fr/Haskell|fr]] <br />
|-<br />
|}<br />
<br />
|valign=top bgcolor=#F0F0F0 width=65% style="text-align:left"|<br />
<br />
<br />
== Eventos ==<br />
{{:Events}}<br />
<br />
<br />
== Headlines ==<br />
<br />
* Haskell.org é a organização mentora no [http://code.google.com/soc 2007 Google Summer of Code]. 9 estudantes foram convidados pelo Google para trabalhar na infraestrutura do projeto para Haskell.<br />
<br />
* O comitê [http://hackage.haskell.org/trac/haskell-prime Haskell-prime] começou a trabalhar para definir a próxima ''minor revision'' da especificação da linguagem.<br />
<br />
* A comunidade Haskell [http://www.haskell.org/communities November 2006] Relatório de Atividades foi criada, documentando projetos para a comunidade Haskell.<br />
<br />
* Haskell, pelo terceiro ano seguido, foi usado por [http://googleresearch.blogspot.com/2006/09/and-awards-go-to.html the winning team] e no [http://www.boundvariable.org/scoreboard.shtml ICFP Programming Contest].<br />
<br />
<br />
== Livros-texto ==<br />
<br />
;[[Image:Uma_Abordagem_Pratica.jpg|Cover]] Claudio Cesar de S and Marcio Ferreira da Silva: <em> Haskell: Uma Abordagem Prática</em>, [http://www.novatec.com.br Novatec Editora Ltda.], 2006, 296 pages, ISBN 85-7522-095-0. The price is R$ 62,00 (in Reais). Language: Portugese<br />
<br />
<blockquote><br />
This book is being published by Novatec Editora Ltda. You can access directly [http://www.novateceditora.com.br/livros/haskell/ here].<br />
<br><br />
<b>Book description:</b><br><br />
This book brings a comprehensive vision of Haskell language. No <br />
knowledge in another functional programming language is expected. In <br />
addition, no background in programming is required. The book presents <br />
issues from basic up to an intermediate level; it also includes some <br />
advanced aspects of Haskell. The title of the book, <em>Haskell: Uma <br />
Abordagem Prtica</em>, in English <em>Haskell: A Practical Approach</em>, is the essence of the book.<br />
The result is a text that can be used in courses of programming and paradigms languages.<br />
Finally, many practical examples can be found <br />
throughout the book.<br />
<br />
An additional page containing comments on this book is found here:<br />
[http://www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell].<br />
Other data as bibtex entry, cover's book in several formats, <br />
Winhugs-2001 for download, and so on. This page is Portugese.<br />
</blockquote><br />
<br />
<br />
== Notícias ==<br />
{{:News}}<br />
<br />
|}<br />
<br />
== Articles ==<br />
<br />
[[Category:Community]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Template:Main/Events&diff=13227Template:Main/Events2007-05-25T16:02:13Z<p>Heisenbug: oops</p>
<hr />
<div>{| border="0" cellspacing="0" cellpadding="2"<br />
! <br />
!<br />
!<br />
|-<br />
| [http://www.londonhug.net/2007/04/26/announcement-first-meeting-of-the-london-haskell-user-group/ London Haskell User Group]<br />
| London/UK<br />
| May 23, 2007<br />
|-<br />
| [http://research.ihost.com/hopl/ HOPL-III]<br />
| San Diego/California<br />
| June 9-10, 2007<br />
|-<br />
| [http://www.comp.mq.edu.au/plrg/sapling.html SAPLING]<br />
| Sydney/Australia<br />
| June 12, 2007<br />
|-<br />
| [http://www.dcs.gla.ac.uk/research/spls/ Scottish Programming Languages Seminar]<br />
| St Andrews/Scotland<br />
| June 14, 2007<br />
|-<br />
| [http://cs.ubbcluj.ro/cefp2007/ CEFP]<br />
| Cluj-Napoca/Romania<br />
| June 23-30, 2007<br />
|-<br />
| [http://iba-cg.de/haskell.html HaL2 - Haskell in Leipzig]<br />
| Leipzig/Germany<br />
| July 10, 2007<br />
|-<br />
| [http://www.icfpcontest.org/ ICFP Programming Contest 2007]<br />
| Anywhere<br />
| July 20-23, 2007<br />
|-<br />
| [http://f.loulergue.free.fr/HLPP/hlpp2007/ High-level Parallel Programming Workshop]<br />
| Tokyo/Japan<br />
| July 23-24, 2007<br />
|-<br />
| [http://proglang.informatik.uni-freiburg.de/IFL2007/ IFL]<br />
| Freiburg/Germany<br />
| September 27-29, 2007<br />
|-<br />
| [http://www.cse.unsw.edu.au/~keller/haskellws/HaskellWorkshop.html Haskell Workshop]<br />
| Freiburg/Germany<br />
| September 30, 2007<br />
|-<br />
| [http://www.informatik.uni-bonn.de/~ralf/icfp07.html ICFP]<br />
| Freiburg/Germany<br />
| October 1-3 2007<br />
|-<br />
| [http://www.cs.uu.nl/~johanj/FPDag2008/ FPDag]<br />
| Utrecht/Netherlands<br />
| January 11, 2008<br />
|-<br />
|}<br />
<br />
[[Category:Events]]</div>Heisenbughttps://wiki.haskell.org/index.php?title=Template:Main/Events&diff=13226Template:Main/Events2007-05-25T15:45:56Z<p>Heisenbug: added HaL2</p>
<hr />
<div>{| border="0" cellspacing="0" cellpadding="2"<br />
! <br />
!<br />
!<br />
|-<br />
| [http://www.londonhug.net/2007/04/26/announcement-first-meeting-of-the-london-haskell-user-group/ London Haskell User Group]<br />
| London/UK<br />
| May 23, 2007<br />
|-<br />
| [http://research.ihost.com/hopl/ HOPL-III]<br />
| San Diego/California<br />
| June 9-10, 2007<br />
|-<br />
| [http://www.comp.mq.edu.au/plrg/sapling.html SAPLING]<br />
| Sydney/Australia<br />
| June 12, 2007<br />
|-<br />
| [http://www.dcs.gla.ac.uk/research/spls/ Scottish Programming Languages Seminar]<br />
| St Andrews/Scotland<br />
| June 14, 2007<br />
|-<br />
| [http://cs.ubbcluj.ro/cefp2007/ CEFP]<br />
| Cluj-Napoca/Romania<br />
| June 23-30, 2007<br />
|-<br />
| [http://iba-cg.de/haskell.html/ HaL2 - Haskell in Leipzig]<br />
| Leipzig/Germany<br />
| July 10, 2007<br />
|-<br />
| [http://www.icfpcontest.org/ ICFP Programming Contest 2007]<br />
| Anywhere<br />
| July 20-23, 2007<br />
|-<br />
| [http://f.loulergue.free.fr/HLPP/hlpp2007/ High-level Parallel Programming Workshop]<br />
| Tokyo/Japan<br />
| July 23-24, 2007<br />
|-<br />
| [http://proglang.informatik.uni-freiburg.de/IFL2007/ IFL]<br />
| Freiburg/Germany<br />
| September 27-29, 2007<br />
|-<br />
| [http://www.cse.unsw.edu.au/~keller/haskellws/HaskellWorkshop.html Haskell Workshop]<br />
| Freiburg/Germany<br />
| September 30, 2007<br />
|-<br />
| [http://www.informatik.uni-bonn.de/~ralf/icfp07.html ICFP]<br />
| Freiburg/Germany<br />
| October 1-3 2007<br />
|-<br />
| [http://www.cs.uu.nl/~johanj/FPDag2008/ FPDag]<br />
| Utrecht/Netherlands<br />
| January 11, 2008<br />
|-<br />
|}<br />
<br />
[[Category:Events]]</div>Heisenbug