https://wiki.haskell.org/api.php?action=feedcontributions&user=JeffFoster&feedformat=atomHaskellWiki - User contributions [en]2020-02-26T17:55:11ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=CamHac/PostHackathonReport&diff=41599CamHac/PostHackathonReport2011-08-14T14:39:10Z<p>JeffFoster: </p>
<hr />
<div>= Post-Hackathon Report =<br />
<br />
This page is for listing what was done during the Hackathon. Please add a short description of what you worked on, with links to relevant blog posts, hackage packages, commits, etc.<br />
<br />
== fclabels 1.0 release ==<br />
<br />
New release of the '''fclabels''' package. The new package has a lot of code and documentation cleanups, support for partial labels in the case of multi-constructor datatypes and is about 20x as fast for setting and modifying as the previous version. Thanks everyone for helping me out!<br />
<br />
Hackage: http://hackage.haskell.org/package/fclabels-1.0.1<br />
<br />
Github: http://github.com/sebastiaanvisser/fclabels<br />
<br />
== GHC and base library improvements ==<br />
<br />
* [http://hackage.haskell.org/trac/ghc/ticket/5413 Add primops for bit population count]. These primops compile down to `POPCNT` instructions where available and fast fallbacks (implemented in C) otherwise.<br />
<br />
* [http://hackage.haskell.org/trac/ghc/ticket/5414 Add unchecked left and right bit shifts]: The Data.Bits.shift method uses a branch to check if the shift amount is larger than the word size and returns 0 in these cases. This extra safety makes performance worse in bit twiddling code.<br />
<br />
* Discussed unpacking of enums in GHC (not yet implemented).<br />
<br />
== Darcs ==<br />
<br />
New contributors:<br />
<br />
* use red text to report when <font color="red">we have a conflict</font> ([http://bugs.darcs.net/issue1681 issue1681],[http://bugs.darcs.net/patch646 patch646], Jeff Foster)<br />
* support 'since' in English dates parser<br />
* filter SSH output ([http://bugs.darcs.net/issue845 issue845], Jeff Foster and Sebastian Korten)<br />
* support arbitrary darcs command in darcs-test (Alexander Njemz)<br />
* output ISO dates in darcs changes? ([http://bugs.darcs.net/issue140 issue140], Alexander N, may be not a good idea)<br />
* add a last regrets prompt to interactive patch selection ([http://bugs.darcs.net/issue1920 issue1920], [http://bugs.darcs.net/patch655 patch655], Johannes Weiß)<br />
* [in-progress] support removing changes in amend-record ([http://bugs.darcs.net/issue1470 issue1470], Johannes Weiß)<br />
<br />
== wxHaskell ==<br />
<br />
* a Windows build fix ([https://sourceforge.net/mailarchive/forum.php?thread_name=CAA5%3D7kb%2BCmJ178tvrxtOnuswWBeBxYpSotiQWRXuKE3m_sByXA%40mail.gmail.com&forum_name=wxhaskell-devel patch])<br />
* a fix for [https://sourceforge.net/tracker/?func=detail&aid=3019730&group_id=73133&atid=536845 an issue with colorDialog] ([https://sourceforge.net/mailarchive/forum.php?thread_name=20110813150933.GA758%40dewdrop.local&forum_name=wxhaskell-devel patch])<br />
<br />
== hCole-server ==<br />
<br />
* A Snap-based web application that interacts with the COLE (see http://portal.acm.org/citation.cfm?id=1356080 and http://portal.acm.org/citation.cfm?id=1772965) framework for exploring compiler optimisation levels. The purpose of the web app is that collaborators can submit optimisation sequences to the COLE backend and retrieve the results when they are available after measuring.<br />
* Git repository of the web application can be found at https://github.com/itkovian/hcole-server<br />
<br />
== GObject Introspection ==<br />
<br />
* Work-in-progress binding generator for GObject-based libraries such as Gtk+ 3.<br />
* Started switching to [http://hackage.haskell.org/package/haskell-src-exts-1.11.1 haskell-src-exts] for code generation.<br />
* Patches currently on the ''camhac'' branch on [https://gitorious.org/haskell-gi/haskell-gi gitorious].<br />
<br />
== Snap Framework ==<br />
<br />
* Some work has been done on the authentication Snaplet, including an (incomplete) HDBC backend for it. An early work-in-progress can be found here: https://github.com/norm2782/snap<br />
* An example application which uses Snap 0.6 has been improved to use the authentication Snaplet. Another work-in-progress: https://github.com/norm2782/snap-guestbook<br />
<br />
== Data.Text ==<br />
<br />
* Further benchmarking, bug fixing to support the UTF-8 port. Progress can be found in the ''utf8'' branch here: http://github.com/jaspervdj/text<br />
<br />
== hs-poker ==<br />
<br />
* A "redneck naive" poker hand evaluator. Code is on github (https://github.com/fffej/HS-Poker). Hopefully intend to turn this into a poker bot playground for Haskell (Jeff / Sebastian)</div>JeffFosterhttps://wiki.haskell.org/index.php?title=CamHac&diff=41567CamHac2011-08-13T08:01:22Z<p>JeffFoster: /* Projects */</p>
<hr />
<div>Haskell Hackaton in Cambridge, UK, '''August 12-14, 2011'''<br />
<br />
== About ==<br />
<br />
Come and spend a weekend in Cambridge hacking Haskell code in great surroundings with fantastic company! Haskell Hackathons are a tradition where everyone is welcome; we get together, work on projects with others or just do your own thing, the overall goal being to improve the Haskell ecosystem.<br />
<br />
CamHac will be held from 12-14 August 2011, at [http://www.homertonconference.com/ Homerton College] in Cambridge. As with previous Hackathons, all are welcome -- you do not have to be a Haskell guru. All you need is a basic knowledge of Haskell, a willingness to learn, and a project you're excited to help with (or a project of your own to work on).<br />
<br />
There will be lots of hacking, good food, and, of course, fun! <br />
<br />
* Organiser: [mailto:marlowsd@gmail.com Simon Marlow] (<tt>JaffaCake</tt> on IRC)<br />
* Mailing list: [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org]<br />
* IRC channel: #camhac on FreeNode<br />
<br />
Many thanks to [http://research.microsoft.com/en-us/labs/cambridge/default.aspx Microsoft Research Cambridge] for agreeing to sponsor the event.<br />
<br />
== Registration ==<br />
<br />
'''We are full, sorry!''' All 72 places are currently allocated.<br />
<br />
We do have a waiting list, which we will use to allocate places if people drop out. If you would like to be added to it, please email [mailto:msrcevnt@microsoft.com msrcevnt@microsoft.com] stating that you would like to be added to the waiting list for the "Haskell Hackathon", with the following information<br />
<br />
Full name:<br />
Which days you are attending on:<br />
day 1: yes/no<br />
day 2: yes/no<br />
day 3: yes/no<br />
Dietary requirements:<br />
<br />
== Venue ==<br />
<br />
We're in the [http://www.homertonconference.com/Leah-Manning.html Leah Manning Room] of [http://www.homertonconference.com/ Homerton Conference Centre]. It is about [http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 15 minutes walk from the train station], and Cambridge town centre is about 30 minutes walk.<br />
<br />
'''Times''': <br />
* 0900: arrive any time from 9am, coffee and snacks will be available until 1000. Make sure you pick up your name badge and wifi details from the registration desk on arrival.<br />
* 1045: break (coffee/tea, biscuits)<br />
* 1230: lunch<br />
* 1500: break (coffee/tea, cake)<br />
* 1730: finish (we might be able to extend this a little if necessary)<br />
<br />
There will be WiFi access, you will be given details when you arrive. We've been told that extra WiFi has been installed in the meeting room for us.<br />
<br />
<br />
There will be a projector for giving talks/demos. We will probably reserve a part of the time for talks and demos.<br />
<br />
== Food ==<br />
<br />
Tea and coffee will be supplied. We will have to go out to find lunch, but there are various places to eat and buy food at the [http://www.cambridge-x.co.uk Cambridge Leisure Park] a few minutes walk towards Cambridge town centre. In the evening we will probably head towards the town where there are plenty of good restaurants.<br />
<br />
We have been advised that only food provided by or purchased from Homerton College can be consumed on the premises.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Cambridge ===<br />
<br />
==== By Plane ====<br />
<br />
* [http://www.stanstedairport.com/ Stansted Airport]: Stansted is the nearest of the London-area airports to Cambridge. It is mostly served by flights to and from mainland Europe, Ireland, and elsewhere in the UK. By train it is about 30 minutes to Cambridge, bus about 1 hour.<br />
<br />
* [http://www.heathrowairport.com/ Heathrow Airport]: Heathrow is the principal London-area airport and one of the busiest in Europe with a wide range of national, European, and international services. By train it is about 1h30 to 2h to Cambridge (Heathrow Express is faster but more expensive).<br />
<br />
* [http://www.gatwickairport.com/ Gatwick Airport]: Gatwick is the second "London" airport with a wide range of national, European and international services. By train it is about 2h to Cambridge.<br />
<br />
* Other airports: [http://www.london-luton.co.uk/ Luton Airport], [http://www.norwichairport.co.uk/ Norwich airport], and [http://www.southendairport.com/ Southend airport] are other regional airports in the East Anglia region. If you use these, car or taxi is the best option for travel to Cambridge.<br />
<br />
==== Trains from London ====<br />
<br />
London has two train lines into Cambridge, London Kings Cross and London Liverpool Street. There is a regular service on both lines and duration is under an hour on the direct trains. Go to [http://www.nationalrail.co.uk National Rail] to check train times.<br />
<br />
You can usually buy tickets at the station both at a ticket machine or a staffed counter. You usually will ''not'' be able to buy tickets on the train without paying a fine. Tickets can be cheaper if you buy off-peak and return trip. Off-peak tickets are usually valid on weekends and after 10 a.m. on weekdays. Make sure, though, to check [http://www.nationalrail.co.uk National Rail] for which trains are eligible for off-peak tickets.<br />
<br />
=== Getting to the venue ===<br />
<br />
[http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 Walk from the train station] (about 15 minutes)<br />
<br />
[http://www.homertonconference.com/How-to-find-us.html How to find the venue]<br />
<br />
'''Local Taxis''': Panther Taxis 01223 715715<br />
<br />
=== Accommodation ===<br />
<br />
[http://www.visitcambridge.org/VisitCambridge/WhereToStay.aspx VisitCambridge: Where to Stay in Cambridge]<br />
<br />
The nearest hotels to the venue seem to be:<br />
<br />
* [http://www2.travelodge.co.uk/ Travelodge] (Cambridge Central) is just a few minutes walk from the venue. It is currently charging £65.80 per night for 11-14 August.<br />
* [http://www.helenhotel.co.uk/index.htm Helen Hotel]<br />
* [http://www.bandbincambridgeshire.co.uk/ Bridge Guest House]<br />
* [http://www.cheapguesthouses.com/ Fairways Guest House]<br />
* [http://www.abbeyfieldguesthouse.com/ Abbeyfield Guest House]<br />
* [http://rockviewguesthouse.co.uk/default.aspx Rock View Guest House]<br />
* [http://alingtonhouse.com/default.aspx Alington House Guest House]<br />
* [http://www.yha.org.uk/find-accommodation/east-of-england/hostels/cambridge/index.aspx Cambridge Youth Hostel]. The hostel does not offer single rooms, but you might be able to organise a group to occupy one 4-bed room.<br />
* [http://www.cambridgerooms.co.uk/ Stay in Cambridge Colleges]<br />
<br />
If you contact any of the above and find they're booked up, please remove them from the list.<br />
<br />
Microsoft Research recommends the following hotels to visitors, these are closer to the city centre but are probably a lot more expensive than those above:<br />
<br />
* [http://www.hilton.co.uk/cambridgegardenhouse Double Tree by Hilton Garden House Cambridge]<br />
* [http://www.ichotelsgroup.com/h/d/cp/1/en/hotel/cbguk Crowne Plaza Cambridge]<br />
* [http://www.devere.co.uk/our-locations/university-arms.html De Vere University Arms]<br />
<br />
== Projects ==<br />
<br />
Use this space to list projects you are interested in working on, and add your name to projects you are interested in helping with.<br />
<br />
* General hacking away at Snap Framework (exact goals TBD), perhaps adding/improving documentation/tutorials at the same time. (Jurriën Stutterheim, Twey)<br />
* Darcs<br />
* Something games/3d related? (Stephen L) [edit: can't think of anything gamesy, so probably will do some graph data-mining stuff] <br />
* [http://code.google.com/p/lambdacube LambdaCube 3D engine] (Csaba Hruska)<br />
** Discussion about graphics pipeline DSL<br />
* Designing/proposing/implementing a new low-level network package, similar in role to 'network' itself (Ben Millwood, Twey)<br />
** See also [[User:benmachine/New network package]]<br />
* A service to help find or contribute examples of usage of a package, under hackage, github.<br />
** Or a clone of Carcassonne (a board game). - [[User:Neillb|Neillb]]<br />
* Writing a library that implements the ideas of [http://web.cecs.pdx.edu/~mpj/thih/ Typing Haskell In Haskell] to type-check, say, a haskell-src-exts AST (Ben Millwood, Stijn van Drongelen)<br />
** I've been advised that THIH is actually quite old, and I might want to find a different base to work from. Any input appreciated. --Ben<br />
*** Use a constraint-based approach, like the monadic constraint library that was presented at Anglohaskell the other year. Much more pleasant. --Philippa<br />
*** Since haskell-src-exts includes GHC-specific extensions, why not round-trip via the GHC AST? That could also be used by other tools. --[[User:Nominolo|Nominolo]]<br />
*** Part of the idea was to be more lightweight/modular than GHC, but it would still be a good way to test :) --[[User:Benmachine|benmachine]] 00:22, 12 August 2011 (UTC)<br />
* wxHaskell (Maciek Makowski)<br />
* System.Process: Provide a way to send arbitrary posix signals to a ProcessHandle. [[User:Matthiasg|Matthiasg]] 20:56, 20 June 2011 (UTC)<br />
* Have an option to avoid using package.cache, because it makes working with Open Embedded quite hard. [[User:Matthiasg|Matthiasg]] 15:57, 27 June 2011 (UTC)<br />
* Hackage 2 (Ben Millwood)<br />
* Data.Text (Jasper Van der Jeugt)<br />
* unordered-containers (Johan Tibell)<br />
* I probably deserve a real kicking for this, but: a TeX replacement. Specifically, embed TeX in Haskell so you can both parse down to its semantic layer and manipulate the semantic layer stuff (which is still pretty-printable back out to TeX as a bunch of primitives and not-so-primitives). Got a bunch of ideas for this, but it's mostly an itch I just got - am currently reading through the TeXbook to check I've understood how TeX itself works sufficiently though, and who doesn't want a backwards-compatible-including-extensions TeX replacement with better syntax, typechecking and the potential for better debugging? --[[User:PhilippaCowderoy|PhilippaCowderoy]] 22:04, 3 August 2011 (UTC)<br />
** Not going to be there, so unless anyone's feeling particularly brave I'm guessing this one's a goner.<br />
* Cabal, cabal-install, Haskell Platform, nixpkgs (Andres Loeh)<br />
* A NumPy / PDL style scientific library (Jacek Generowicz)<br />
<br />
== Talks/demos ==<br />
<br />
If you have a talk or demo you want to give, add your name to the list below. Let's restrict these to short slots (say 20 mins max). Tentatively we'll have a session of talks and demos on Saturday afternoon, but we can always move things around if necessary.<br />
<br />
== Attendees ==<br />
<br />
# Simon Marlow<br />
# Jurriën Stutterheim<br />
# Neil Mitchell<br />
# Jasper Van der Jeugt<br />
# Max Bolingbroke<br />
# Ben Millwood ‘benmachine’<br />
# Roman Leshchinskiy<br />
# Gregory Collins<br />
# Martijn van Steenbergen<br />
# Sjoerd Visscher<br />
# Sebastiaan Visser<br />
# Tom Lokhorst<br />
# Erik Hesselink<br />
# Jeff Foster<br />
# Sebastian Korten<br />
# Alessandro Vermeulen<br />
# Vlad Hanciuta<br />
# Ganesh Sittampalam<br />
# Eric Kow<br />
# Alexander Njemz<br />
# Mikolaj Konarski<br />
# Ian Lynagh<br />
# Andres Löh<br />
# Jeroen Janssen<br />
# Nicolas Wu<br />
# Duncan Coutts<br />
# Dominic Orchard<br />
# Jacek Generowicz<br />
# Owen Stephens<br />
# Stephen Lavelle<br />
# Sam Martin<br />
# Alex Horsman<br />
# Andy Georges<br />
# Niklas Larsson<br />
# Raeez Lorgat<br />
# Maryna Strelchuk<br />
# Vincent Hanquez<br />
# Chris Done<br />
# Tomas Petricek<br />
# Thomas Schilling<br />
# Dragos Ionita<br />
# Simon Meier<br />
# Will Thompson<br />
# Sergii Strelchuk<br />
# Lennart Kolmodin<br />
# Steven Keuchel<br />
# Michal Terepeta<br />
# Maciek Makowski<br />
# Johannes Weiß<br />
# Alejandro Serrano<br />
# Mike McClurg<br />
# Stefan Wehr<br />
# David Leuschner<br />
# James ‘Twey’ Kay<br />
# Simon PJ<br />
# Neill Bogie<br />
# Csaba Hruska<br />
# Bart Coppens<br />
# Stijn van Drongelen<br />
# Jeremy Yallop<br />
# Paul Wilson<br />
# Dmitry Astapov<br />
# Matthias Görgens<br />
# Johan Tibell<br />
# Ian Knopke<br />
# A O Van Emmenis<br />
<br />
* Add your name here, once registered...</div>JeffFosterhttps://wiki.haskell.org/index.php?title=CamHac&diff=41556CamHac2011-08-12T09:08:51Z<p>JeffFoster: /* Projects */</p>
<hr />
<div>Haskell Hackaton in Cambridge, UK, '''August 12-14, 2011'''<br />
<br />
== About ==<br />
<br />
Come and spend a weekend in Cambridge hacking Haskell code in great surroundings with fantastic company! Haskell Hackathons are a tradition where everyone is welcome; we get together, work on projects with others or just do your own thing, the overall goal being to improve the Haskell ecosystem.<br />
<br />
CamHac will be held from 12-14 August 2011, at [http://www.homertonconference.com/ Homerton College] in Cambridge. As with previous Hackathons, all are welcome -- you do not have to be a Haskell guru. All you need is a basic knowledge of Haskell, a willingness to learn, and a project you're excited to help with (or a project of your own to work on).<br />
<br />
There will be lots of hacking, good food, and, of course, fun! <br />
<br />
* Organiser: [mailto:marlowsd@gmail.com Simon Marlow] (<tt>JaffaCake</tt> on IRC)<br />
* Mailing list: [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org]<br />
* IRC channel: #ghc on FreeNode<br />
<br />
Many thanks to [http://research.microsoft.com/en-us/labs/cambridge/default.aspx Microsoft Research Cambridge] for agreeing to sponsor the event.<br />
<br />
== Registration ==<br />
<br />
'''We are full, sorry!''' All 72 places are currently allocated.<br />
<br />
We do have a waiting list, which we will use to allocate places if people drop out. If you would like to be added to it, please email [mailto:msrcevnt@microsoft.com msrcevnt@microsoft.com] stating that you would like to be added to the waiting list for the "Haskell Hackathon", with the following information<br />
<br />
Full name:<br />
Which days you are attending on:<br />
day 1: yes/no<br />
day 2: yes/no<br />
day 3: yes/no<br />
Dietary requirements:<br />
<br />
== Venue ==<br />
<br />
We're in the [http://www.homertonconference.com/Leah-Manning.html Leah Manning Room] of [http://www.homertonconference.com/ Homerton Conference Centre]. It is about [http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 15 minutes walk from the train station], and Cambridge town centre is about 30 minutes walk.<br />
<br />
'''Times''': <br />
* 0900: arrive any time from 9am, coffee and snacks will be available until 1000. Make sure you pick up your name badge and wifi details from the registration desk on arrival.<br />
* 1045: break (coffee/tea, biscuits)<br />
* 1230: lunch<br />
* 1500: break (coffee/tea, cake)<br />
* 1730: finish (we might be able to extend this a little if necessary)<br />
<br />
There will be WiFi access, you will be given details when you arrive. We've been told that extra WiFi has been installed in the meeting room for us.<br />
<br />
<br />
There will be a projector for giving talks/demos. We will probably reserve a part of the time for talks and demos.<br />
<br />
== Food ==<br />
<br />
Tea and coffee will be supplied. We will have to go out to find lunch, but there are various places to eat and buy food at the [http://www.cambridge-x.co.uk Cambridge Leisure Park] a few minutes walk towards Cambridge town centre. In the evening we will probably head towards the town where there are plenty of good restaurants.<br />
<br />
We have been advised that only food provided by or purchased from Homerton College can be consumed on the premises.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Cambridge ===<br />
<br />
==== By Plane ====<br />
<br />
* [http://www.stanstedairport.com/ Stansted Airport]: Stansted is the nearest of the London-area airports to Cambridge. It is mostly served by flights to and from mainland Europe, Ireland, and elsewhere in the UK. By train it is about 30 minutes to Cambridge, bus about 1 hour.<br />
<br />
* [http://www.heathrowairport.com/ Heathrow Airport]: Heathrow is the principal London-area airport and one of the busiest in Europe with a wide range of national, European, and international services. By train it is about 1h30 to 2h to Cambridge (Heathrow Express is faster but more expensive).<br />
<br />
* [http://www.gatwickairport.com/ Gatwick Airport]: Gatwick is the second "London" airport with a wide range of national, European and international services. By train it is about 2h to Cambridge.<br />
<br />
* Other airports: [http://www.london-luton.co.uk/ Luton Airport], [http://www.norwichairport.co.uk/ Norwich airport], and [http://www.southendairport.com/ Southend airport] are other regional airports in the East Anglia region. If you use these, car or taxi is the best option for travel to Cambridge.<br />
<br />
==== Trains from London ====<br />
<br />
London has two train lines into Cambridge, London Kings Cross and London Liverpool Street. There is a regular service on both lines and duration is under an hour on the direct trains. Go to [http://www.nationalrail.co.uk National Rail] to check train times.<br />
<br />
You can usually buy tickets at the station both at a ticket machine or a staffed counter. You usually will ''not'' be able to buy tickets on the train without paying a fine. Tickets can be cheaper if you buy off-peak and return trip. Off-peak tickets are usually valid on weekends and after 10 a.m. on weekdays. Make sure, though, to check [http://www.nationalrail.co.uk National Rail] for which trains are eligible for off-peak tickets.<br />
<br />
=== Getting to the venue ===<br />
<br />
[http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 Walk from the train station] (about 15 minutes)<br />
<br />
[http://www.homertonconference.com/How-to-find-us.html How to find the venue]<br />
<br />
'''Local Taxis''': Panther Taxis 01223 715715<br />
<br />
=== Accommodation ===<br />
<br />
[http://www.visitcambridge.org/VisitCambridge/WhereToStay.aspx VisitCambridge: Where to Stay in Cambridge]<br />
<br />
The nearest hotels to the venue seem to be:<br />
<br />
* [http://www2.travelodge.co.uk/ Travelodge] (Cambridge Central) is just a few minutes walk from the venue. It is currently charging £65.80 per night for 11-14 August.<br />
* [http://www.helenhotel.co.uk/index.htm Helen Hotel]<br />
* [http://www.bandbincambridgeshire.co.uk/ Bridge Guest House]<br />
* [http://www.cheapguesthouses.com/ Fairways Guest House]<br />
* [http://www.abbeyfieldguesthouse.com/ Abbeyfield Guest House]<br />
* [http://rockviewguesthouse.co.uk/default.aspx Rock View Guest House]<br />
* [http://alingtonhouse.com/default.aspx Alington House Guest House]<br />
* [http://www.yha.org.uk/find-accommodation/east-of-england/hostels/cambridge/index.aspx Cambridge Youth Hostel]. The hostel does not offer single rooms, but you might be able to organise a group to occupy one 4-bed room.<br />
* [http://www.cambridgerooms.co.uk/ Stay in Cambridge Colleges]<br />
<br />
If you contact any of the above and find they're booked up, please remove them from the list.<br />
<br />
Microsoft Research recommends the following hotels to visitors, these are closer to the city centre but are probably a lot more expensive than those above:<br />
<br />
* [http://www.hilton.co.uk/cambridgegardenhouse Double Tree by Hilton Garden House Cambridge]<br />
* [http://www.ichotelsgroup.com/h/d/cp/1/en/hotel/cbguk Crowne Plaza Cambridge]<br />
* [http://www.devere.co.uk/our-locations/university-arms.html De Vere University Arms]<br />
<br />
== Projects ==<br />
<br />
Use this space to list projects you are interested in working on, and add your name to projects you are interested in helping with.<br />
<br />
* General hacking away at Snap Framework (exact goals TBD), perhaps adding/improving documentation/tutorials at the same time. (Jurriën Stutterheim, Twey)<br />
* Darcs<br />
* Something games/3d related? (Stephen L) [edit: can't think of anything gamesy, so probably will do some graph data-mining stuff] <br />
* [http://code.google.com/p/lambdacube LambdaCube 3D engine] (Csaba Hruska)<br />
** Discussion about graphics pipeline DSL<br />
* Designing/proposing/implementing a new low-level network package, similar in role to 'network' itself (Ben Millwood, Twey)<br />
** See also [[User:benmachine/New network package]]<br />
* A service to help find or contribute examples of usage of a package, under hackage, github.<br />
** Or a clone of Carcassonne (a board game). - [[User:Neillb|Neillb]]<br />
* Writing a library that implements the ideas of [http://web.cecs.pdx.edu/~mpj/thih/ Typing Haskell In Haskell] to type-check, say, a haskell-src-exts AST (Ben Millwood, Stijn van Drongelen)<br />
** I've been advised that THIH is actually quite old, and I might want to find a different base to work from. Any input appreciated. --Ben<br />
*** Use a constraint-based approach, like the monadic constraint library that was presented at Anglohaskell the other year. Much more pleasant. --Philippa<br />
*** Since haskell-src-exts includes GHC-specific extensions, why not round-trip via the GHC AST? That could also be used by other tools. --[[User:Nominolo|Nominolo]]<br />
*** Part of the idea was to be more lightweight/modular than GHC, but it would still be a good way to test :) --[[User:Benmachine|benmachine]] 00:22, 12 August 2011 (UTC)<br />
* wxHaskell (Maciek Makowski)<br />
* System.Process: Provide a way to send arbitrary posix signals to a ProcessHandle. [[User:Matthiasg|Matthiasg]] 20:56, 20 June 2011 (UTC)<br />
* Have an option to avoid using package.cache, because it makes working with Open Embedded quite hard. [[User:Matthiasg|Matthiasg]] 15:57, 27 June 2011 (UTC)<br />
* Hackage 2 (Ben Millwood)<br />
* Data.Text (Jasper Van der Jeugt)<br />
* unordered-containers (Johan Tibell)<br />
* I probably deserve a real kicking for this, but: a TeX replacement. Specifically, embed TeX in Haskell so you can both parse down to its semantic layer and manipulate the semantic layer stuff (which is still pretty-printable back out to TeX as a bunch of primitives and not-so-primitives). Got a bunch of ideas for this, but it's mostly an itch I just got - am currently reading through the TeXbook to check I've understood how TeX itself works sufficiently though, and who doesn't want a backwards-compatible-including-extensions TeX replacement with better syntax, typechecking and the potential for better debugging? --[[User:PhilippaCowderoy|PhilippaCowderoy]] 22:04, 3 August 2011 (UTC)<br />
** Not going to be there, so unless anyone's feeling particularly brave I'm guessing this one's a goner.<br />
* Cabal, cabal-install, Haskell Platform, nixpkgs (Andres Loeh)<br />
* A NumPy / PDL style scientific library<br />
* Some information retrieval algorithms (aiming at Lucene in Haskell) (Jeff Foster)<br />
<br />
== Talks/demos ==<br />
<br />
If you have a talk or demo you want to give, add your name to the list below. Let's restrict these to short slots (say 20 mins max). Tentatively we'll have a session of talks and demos on Saturday afternoon, but we can always move things around if necessary.<br />
<br />
== Attendees ==<br />
<br />
# Simon Marlow<br />
# Jurriën Stutterheim<br />
# Neil Mitchell<br />
# Jasper Van der Jeugt<br />
# Max Bolingbroke<br />
# Ben Millwood ‘benmachine’<br />
# Roman Leshchinskiy<br />
# Gregory Collins<br />
# Martijn van Steenbergen<br />
# Sjoerd Visscher<br />
# Sebastiaan Visser<br />
# Tom Lokhorst<br />
# Erik Hesselink<br />
# Jeff Foster<br />
# Sebastian Korten<br />
# Alessandro Vermeulen<br />
# Vlad Hanciuta<br />
# Ganesh Sittampalam<br />
# Eric Kow<br />
# Alexander Njemz<br />
# Mikolaj Konarski<br />
# Ian Lynagh<br />
# Andres Löh<br />
# Jeroen Janssen<br />
# Nicolas Wu<br />
# Duncan Coutts<br />
# Dominic Orchard<br />
# Jacek Generowicz<br />
# Owen Stephens<br />
# Stephen Lavelle<br />
# Sam Martin<br />
# Alex Horsman<br />
# Andy Georges<br />
# Niklas Larsson<br />
# Raeez Lorgat<br />
# Maryna Strelchuk<br />
# Vincent Hanquez<br />
# Chris Done<br />
# Tomas Petricek<br />
# Thomas Schilling<br />
# Dragos Ionita<br />
# Simon Meier<br />
# Will Thompson<br />
# Sergii Strelchuk<br />
# Lennart Kolmodin<br />
# Steven Keuchel<br />
# Michal Terepeta<br />
# Maciek Makowski<br />
# Johannes Weiß<br />
# Alejandro Serrano<br />
# Mike McClurg<br />
# Stefan Wehr<br />
# David Leuschner<br />
# James ‘Twey’ Kay<br />
# Simon PJ<br />
# Neill Bogie<br />
# Csaba Hruska<br />
# Bart Coppens<br />
# Stijn van Drongelen<br />
# Jeremy Yallop<br />
# Paul Wilson<br />
# Dmitry Astapov<br />
# Matthias Görgens<br />
# Johan Tibell<br />
# Ian Knopke<br />
# A O Van Emmenis<br />
<br />
* Add your name here, once registered...</div>JeffFosterhttps://wiki.haskell.org/index.php?title=CamHac&diff=40143CamHac2011-05-26T22:59:50Z<p>JeffFoster: /* Attendees */</p>
<hr />
<div>Haskell Hackaton in Cambridge, UK, '''August 12-14, 2011'''<br />
<br />
== About ==<br />
<br />
Come and spend a weekend in Cambridge hacking Haskell code in great surroundings with fantastic company! Haskell Hackathons are a tradition where everyone is welcome; we get together, work on projects with others or just do your own thing, the overall goal being to improve the Haskell ecosystem.<br />
<br />
CamHac will be held from 12-14 August 2011, at [http://www.homertonconference.com/ Homerton College] in Cambridge. As with previous Hackathons, all are welcome -- you do not have to be a Haskell guru. All you need is a basic knowledge of Haskell, a willingness to learn, and a project you're excited to help with (or a project of your own to work on).<br />
<br />
There will be lots of hacking, good food, and, of course, fun! <br />
<br />
* Organiser: [mailto:marlowsd@gmail.com Simon Marlow] (<tt>JaffaCake</tt> on IRC)<br />
* Mailing list: [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org]<br />
* IRC channel: #ghc on FreeNode<br />
<br />
Many thanks to [http://research.microsoft.com/en-us/labs/cambridge/default.aspx Microsoft Research Cambridge] for agreeing to sponsor the event.<br />
<br />
== Registration ==<br />
<br />
'''Registration deadline''': Friday 15th July 2011<br />
<br />
Registration is free. To register, please email [mailto:msrcevnt@microsoft.com msrcevnt@microsoft.com] stating that you would like to register for the "Haskell Hackathon", with the following information<br />
<br />
Full name:<br />
Which days you are attending on:<br />
day 1: yes/no<br />
day 2: yes/no<br />
day 3: yes/no<br />
Dietary requirements:<br />
<br />
The venue is '''limited to 50 people''', and registration is first-come first-served, so register quickly to reserve your place! (but only register if you definitely intend to come, and please let us know if you find you cannot make it for any reason after you have registered, so we can re-allocate your place).<br />
<br />
== Venue ==<br />
<br />
We're in the [http://www.homertonconference.com/Horobin.html Horobin Room] of [http://www.homertonconference.com/ Homerton Conference Centre]. It is about [http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 15 minutes walk from the train station], and Cambridge town centre is about 30 minutes walk.<br />
<br />
There will be WiFi access.<br />
<br />
There will be a projector for giving talks/demos. We will probably reserve a part of the time for talks and demos.<br />
<br />
== Food ==<br />
<br />
Tea and coffee will be supplied. We will have to go out to find lunch, but there are various places to eat and buy food at the [http://www.cambridge-x.co.uk Cambridge Leisure Park] a few minutes walk towards Cambridge town centre. In the evening we will probably head towards the town where there are plenty of good restaurants.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Cambridge ===<br />
<br />
==== By Plane ====<br />
<br />
* [http://www.stanstedairport.com/ Stansted Airport]: Stansted is the nearest of the London-area airports to Cambridge. It is mostly served by flights to and from mainland Europe, Ireland, and elsewhere in the UK. <br />
<br />
* [http://www.heathrowairport.com/ Heathrow Airport]: Heathrow is the principal London-area airport and one of the busiest in Europe with a wide range of national, European, and international services. <br />
<br />
* [http://www.gatwickairport.com/ Gatwick Airport]: Gatwick is the second "London" airport with a wide range of national, European and international services. <br />
<br />
* Other airports: [http://www.london-luton.co.uk/ Luton Airport], [http://www.norwichairport.co.uk/ Norwich airport], and [http://www.southendairport.com/ Southend airport] are other regional airports in the East Anglia region. If you use these, car or taxi is the best option for travel to Cambridge. <br />
<br />
==== Trains from London ====<br />
<br />
London has two train lines into Cambridge, London Kings Cross and London Liverpool Street. There is a regular service on both lines and duration is under an hour on the direct trains. Go to [http://www.nationalrail.co.uk National Rail] to check train times<br />
<br />
=== Getting to the venue ===<br />
<br />
[http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 Walk from the train station] (about 15 minutes)<br />
<br />
[http://www.homertonconference.com/How-to-find-us.html How to find the venue]<br />
<br />
'''Local Taxis''': Panther Taxis 01223 715715<br />
<br />
=== Accommodation ===<br />
<br />
[http://www.visitcambridge.org/VisitCambridge/WhereToStay.aspx VisitCambridge: Where to Stay in Cambridge]<br />
<br />
The nearest hotels to the venue seem to be:<br />
<br />
* [http://www2.travelodge.co.uk/ Travelodge] (Cambridge Central) is just a few minutes walk from the venue. It is currently charging £65.80 per night for 11-14 August.<br />
* [http://www.helenhotel.co.uk/index.htm Helen Hotel]<br />
* [http://www.bandbincambridgeshire.co.uk/ Bridge Guest House]<br />
* [http://www.cheapguesthouses.com/ Fairways Guest House]<br />
* [http://www.abbeyfieldguesthouse.com/ Abbeyfield Guest House]<br />
* [http://rockviewguesthouse.co.uk/default.aspx Rock View Guest House]<br />
<br />
If you contact any of the above and find they're booked up, please remove them from the list.<br />
<br />
Microsoft Research recommends the following hotels to visitors, these are closer to the city centre but are probably a lot more expensive than those above:<br />
<br />
* [http://www.hilton.co.uk/cambridgegardenhouse Double Tree by Hilton Garden House Cambridge]<br />
* [http://www.ichotelsgroup.com/h/d/cp/1/en/hotel/cbguk Crowne Plaza Cambridge]<br />
* [http://www.devere.co.uk/our-locations/university-arms.html De Vere University Arms]<br />
<br />
== Projects ==<br />
<br />
Use this space to list projects you are interested in working on, and add your name to projects you are interested in helping with.<br />
<br />
* General hacking away at Snap Framework (exact goals TBD), perhaps adding/improving documentation/tutorials at the same time. (Jurriën Stutterheim)<br />
<br />
== Attendees ==<br />
<br />
* Simon Marlow<br />
* Jurriën Stutterheim<br />
* Neil Mitchell<br />
* Jasper Van der Jeugt<br />
* Max Bolingbroke<br />
* Ben Millwood<br />
* Roman Leshchinskiy<br />
* Gregory Collins<br />
* Martijn van Steenbergen<br />
* Sjoerd Visscher<br />
* Sebastiaan Visser<br />
* Tom Lokhorst<br />
* Erik Hesselink<br />
* Jeff Foster<br />
* Add your name here, once registered...</div>JeffFosterhttps://wiki.haskell.org/index.php?title=History_of_Haskell&diff=35107History of Haskell2010-07-06T08:26:30Z<p>JeffFoster: remove spam</p>
<hr />
<div>[[Category:History]]<br />
[[Category:Language]]<br />
== The History of Haskell ==<br />
<br />
[http://doi.acm.org/10.1145/1238844.1238856 A History of Haskell (acm)] [http://research.microsoft.com/~simonpj/papers/history-of-haskell/index.htm (copy)]<br />
<br />
"A History of Haskell: being lazy with class", Paul Hudak (Yale University), John Hughes (Chalmers University), Simon Peyton Jones (Microsoft Research), Philip Wadler (Edinburgh University), The Third ACM SIGPLAN History of Programming Languages Conference (HOPL-III) San Diego, California, June 9-10, 2007.<br />
<br />
This paper describes the history of Haskell, including its genesis and principles, technical contributions, implementations and tools, and applications and impact.<br />
<br />
== Giving feedback ==<br />
<br />
When we publish the final version, we'd like your feedback, because we can still make small changes. You can do so in two ways:<br />
* Send us email personally (simonpj@microsoft.com, wadler@inf.ed.ac.uk, paul.hudak@yale.edu, rjmh@cs.chalmers.se)<br />
* Add comments to [[Talk:History of Haskell/Version 2|the Version 2 "Talk" page]].<br />
<br />
So you can remember what you wrote before<br />
<br />
* Here is [[Talk:History of Haskell/Version 1|the Version 1 "Talk" page]]. I have added notes to it saying what I think I've done, with a few still remaining. Any concrete help with the remaining ToDos would be gratefully received!<br />
<br />
If you like, you can instead send email to the Haskell Cafe mailing list, but we are less likely to follow that closely.<br />
<br />
== Things to think about ==<br />
Writing a paper like this is a big task, and one that is very different to the sort of research papers that we usually write. So we would really appreciate your help in making it better. Here are something thoughts and questions that we invite you to bear in mind as you read it:<br />
<br />
* We experienced a tremendous tension between<br />
** On the one hand, comprehensiveness and doing justice to all those who have contributed to Haskell<br />
** On the other, keeping the paper "alive". We don't want it to become a boring catalogue of everything that has ever happened to Haskell.<br />
: Please don't feel slighted if we have not mentioned your own fantastic work. Instead, politely correct us. And bear in mind that the above tension means that we just can't include everything.<br />
<br />
* We are interested in feedback at all levels: accuracy, coverage, structure, tone, fairness, level of detail; as well as spelling and grammar. Of these, spelling and grammar are the least important!<br />
<br />
* The applications section is particularly patchy. One possibility would be to include a much longer list of applications and application libraries, but given in much less detail. Please send us suggestions: the name of the application, who wrote it, roughly how big it is, and (where posssible) a citation of some kind that gives more detail.</div>JeffFosterhttps://wiki.haskell.org/index.php?title=OOP_vs_type_classes&diff=30089OOP vs type classes2009-09-17T05:52:56Z<p>JeffFoster: minor formatting change</p>
<hr />
<div>(this is just a sketch now. feel free to edit/comment it. I will include information you provided into the final version of this tutorial)<br />
<br />
<br />
I had generally not used type classes in my application programs, but when<br />
I'd gone to implement general purpose libraries and tried to maintain<br />
as much flexibility as possible, it was natural to start building large<br />
and complex class hierarchies. I tried to use my C++ experience when<br />
doing this but I was bitten many times by the restrictions of type classes. After this experience, I think that I now have a better feeling and mind model<br />
for type classes and I want to share it with other Haskellers -<br />
especially ones having OOP backgrounds.<br />
<br />
Brian Hulley provided us with the program that emulates OOP in Haskell - as<br />
you can see, it's much larger than equivalent C++ program. An equivalent translation from Haskell to C++ should be even longer :)<br />
<br />
<br />
== Everything is an object? ==<br />
<br />
You all know this OOP motto - "everything is an object". When I programmed in<br />
C++, it was really hard to do it without classes. But when I, the same<br />
programmer, John de Mac-Lee - use Haskell, it's hard to find open<br />
vacancies for type classes. Why is it so different?<br />
<br />
C++ classes pack functions together with data to make it possible to<br />
use different data representations via the same interface. As long as<br />
you need any of these facilities, you are forced to use classes.<br />
Although C++ supports alternative ways to implement such functionality<br />
(function pointers, discriminated unions), they are not as handy<br />
as classes. Classes are also the sole method of hiding implementation<br />
details. Moreover, classes represent a handy way to group related<br />
functionality together, so I found myself sometimes developing classes that<br />
contain only static functions just to group them into some<br />
'package'. It's extremely useful to browse the structure of large C++ project<br />
in terms of classes instead of individual functions.<br />
<br />
Haskell provides other solutions for these problems.<br />
<br />
=== Type with several representations: use algebraic data type (ADT) ===<br />
<br />
For the types with different representations, algebraic data types<br />
(ADT) - an analog of discriminated unions - are supported:<br />
<br />
<haskell><br />
data Point = FloatPoint Float Float<br />
| IntPoint Int Int<br />
</haskell><br />
<br />
Haskell provides a very easy way to build/analyze them:<br />
<br />
<haskell><br />
coord :: Point -> (Float, Float)<br />
coord (FloatPoint x y) = (x,y)<br />
coord (IntPoint x y) = (realToFrac x, realToFrac y)<br />
<br />
main = do print (coord (FloatPoint 1 2))<br />
print (coord (IntPoint 1 2))<br />
</haskell><br />
<br />
So ADTs in general are preferred in Haskell over the class-based<br />
solution of the same problem:<br />
<br />
<haskell><br />
class Point a where<br />
coord :: a -> (Float, Float)<br />
<br />
data FloatPoint = FloatPoint Float Float<br />
instance Point FloatPoint where<br />
coord (FloatPoint x y) = (x,y)<br />
<br />
data IntPoint = IntPoint Int Int<br />
instance Point IntPoint where<br />
coord (IntPoint x y) = (realToFrac x, realToFrac y)<br />
</haskell><br />
<br />
<br />
You can also imagine all the C++ machinery that is required to implement the<br />
analog of our 5 line, ADT-based solution to say that objects are not<br />
so great as you thought before :D Of course, C++ classes are usually<br />
much larger but that's again Haskell benefit - it's so easy to define<br />
types/functions that you may use much finer granularity.<br />
<br />
<pre><br />
#include <algorithm><br />
#include <iostream><br />
using namespace std;<br />
<br />
ostream & operator<<(ostream & lhs, pair<float, float> const& rhs) {<br />
return lhs << "(" << rhs.first << "," << rhs.second << ")";<br />
}<br />
<br />
struct Point {<br />
virtual pair<float,float> coord() = 0;<br />
};<br />
<br />
struct FloatPoint : Point {<br />
float x, y;<br />
FloatPoint (float _x, float _y) : x(_x), y(_y) {}<br />
pair<float,float> coord() {return make_pair(x,y); }<br />
};<br />
<br />
struct IntPoint : Point {<br />
int x, y;<br />
IntPoint (int _x, int _y) : x(_x), y(_y) {}<br />
pair<float,float> coord() { return make_pair(x,y); }<br />
};<br />
<br />
int main () {<br />
cout << FloatPoint(1,2).coord();<br />
cout << IntPoint(1,2).coord();<br />
return 0;<br />
}<br />
</pre><br />
<br />
As you see, ADTs together with type inference make Haskell programs<br />
about 2 times smaller than their C++ equivalent.<br />
<br />
<br />
=== Packing data & functions together: use (records of) closures ===<br />
<br />
Another typical class use-case is to pack data together with one<br />
or more processing functions and pass this bunch to some<br />
function. Then this function can call the aforementioned functions to implement<br />
some functionality, not bothering how it is implemented internally.<br />
Hopefully Haskell provides a better way: you can pass any functions as parameters to other functions directly.<br />
Moreover, such functions can be constructed on-the-fly, capturing free variables in context, creating the so-called closures. In this way, you construct something like object on-demand and don't even need a type class:<br />
<br />
<haskell><br />
do x <- newIORef 0<br />
proc (modifyIORef x (+1), readIORef x)<br />
</haskell><br />
<br />
Here, we applied proc to two functions - one incrementing the value of a<br />
counter and another reading its current value. Another call to proc<br />
that uses counter with locking, might look like this:<br />
<br />
<haskell><br />
do x <- newMVar 0<br />
proc (modifyMVar x (+1), readMVar x)<br />
</haskell><br />
<br />
Here, proc may be defined as:<br />
<br />
<haskell><br />
proc :: (IO (), IO Int) -> IO ()<br />
proc (inc, read) = do { inc; inc; inc; read >>= print }<br />
</haskell><br />
<br />
<br />
i.e. it receive two abstract operations whose implementation may vary<br />
in different calls to proc and call them without any knowledge of<br />
implementation details. The equivalent C++ code could look like this:<br />
<br />
<pre><br />
class Counter {<br />
public:<br />
virtual void inc() = 0;<br />
virtual int read() = 0;<br />
};<br />
<br />
class SimpleCounter : public Counter {<br />
public:<br />
SimpleCounter() { n = 0; }<br />
void inc() { n++; }<br />
int read() { return n; }<br />
private:<br />
int n;<br />
};<br />
<br />
void proc (Counter c) {<br />
c.inc(); c.inc(); c.inc(); cout << c.read();<br />
}<br />
</pre><br />
<br />
And again, Haskell code is much simpler and more straightforward - we<br />
don't need to declare classes, operations, their types - we just pass<br />
to the proc implementation of operations it needs. Look at<br />
http://haskell.org/haskellwiki/IO_inside#Example:_returning_an_IO_action_as_a_result<br />
and following sections to find more examples of using closures instead<br />
of OOP classes.<br />
<br />
<br />
=== Hiding implementation details: use module export list ===<br />
<br />
One more usage of OOP classes is to hide implementation details, making<br />
internal data/functions inaccessible to class clients. Unfortunately, this<br />
functionality is not part of type class facilities. Instead, you<br />
should use the sole Haskell method of encapsulation, module<br />
export list:<br />
<br />
<haskell><br />
module Stack (Stack, empty, push, pop, top, isEmpty) where<br />
<br />
newtype Stack a = Stk [a]<br />
<br />
empty = Stk []<br />
push x (Stk xs) = Stk (x:xs)<br />
pop (Stk (x:xs)) = Stk xs<br />
top (Stk (x:xs)) = x<br />
isEmpty (Stk xs) = null xs<br />
</haskell><br />
<br />
Since the constructor for the data type Stack is hidden (the export<br />
list would say Stack(Stk) if it were exposed), outside of this module a stack can only be built from operations empty, push and pop, and<br />
examined with top and isEmpty.<br />
<br />
<br />
=== Grouping related functionality: use module hierarchy and Haddock markup ===<br />
<br />
Dividing whole program into classes and using their hierarchy to<br />
represent entire program structure is a great instrument for OO languages. Unfortunately, it's again impossible in Haskell. Instead,<br />
the structure of a program is typically rendered in module hierarchy and inside<br />
module - in its export list. Although Haskell language doesn't provide<br />
facilities to describe hierarchical structure inside of module, we had<br />
another tool to do it - Haddock, a de-facto standard documentation tool.<br />
<br />
<haskell><br />
module System.Stream.Instance (<br />
<br />
-- * File is a file stream<br />
File,<br />
-- ** Functions that open files<br />
openFile, -- open file in text mode<br />
openBinaryFile, -- open file in binary mode<br />
-- ** Standard file handles<br />
stdin,<br />
stdout,<br />
stderr,<br />
<br />
-- * MemBuf is a memory buffer stream<br />
MemBuf,<br />
-- ** Functions that open MemBuf<br />
createMemBuf, -- create new MemBuf<br />
createContiguousMemBuf, -- create new contiguous MemBuf<br />
openMemBuf, -- use memory area as MemBuf<br />
<br />
) where<br />
...<br />
</haskell><br />
<br />
Here, Haddock will build documentation for a module using its export list. The export list will be divided into sections (whose<br />
headers given with "-- *") and subsections (given with "-- **"). As<br />
a result, module documentation reflects its structure without using<br />
classes for this purpose.<br />
<br />
== Type classes is a sort of templates, not classes ==<br />
<br />
At this moment C++/C#/Java languages have classes and<br />
templates/generics. What is a difference? With a class, type<br />
information is carried with object itself while with templates it's<br />
outside of object and is part of the whole operation.<br />
<br />
For example, if == operation is defined in a class, the actual<br />
procedure called for a==b may depend on run-time type of 'a' but if it<br />
is defined in template, actual procedure depends only on template<br />
instantiated (and determined at compile time).<br />
<br />
Haskell's objects don't carry run-time type information. Instead,<br />
class constraint for polymorphic operation is passed in form of a<br />
"dictionary" implementing all operations of the class (there are also<br />
other implementation techniques, but this doesn't matter). For example,<br />
<br />
<haskell><br />
eqList :: (Eq a) => [a] -> [a] -> Bool<br />
</haskell><br />
<br />
is translated into:<br />
<br />
<haskell><br />
type EqDictionary a = (a->a->Bool, a->a->Bool)<br />
eqList :: EqDictionary a -> [a] -> [a] -> Bool<br />
</haskell><br />
<br />
where the first parameter is a "dictionary" containing implementation of<br />
"==" and "/=" operations for objects of type 'a'. If there are several<br />
class constraints, a dictionary for each is passed.<br />
<br />
If class has base class(es), the dictionary tuple also includes tuples<br />
of base classes dictionaries, so<br />
<br />
<haskell><br />
class Eq a => Cmp a where<br />
cmp :: a -> a -> Ordering<br />
<br />
cmpList :: (Cmp a) => [a] -> [a] -> Ordering<br />
</haskell><br />
<br />
turns into:<br />
<br />
<haskell><br />
type CmpDictionary a = (eqDictionary a, a -> a -> Ordering)<br />
cmpList :: CmpDictionary a -> [a] -> [a] -> Bool<br />
</haskell><br />
<br />
<br />
Comparing to C++, this is more like the templates, not classes! As with<br />
templates, type information is part of operation, not object! But<br />
while C++ templates are really form of macro-processing (like<br />
Template Haskell) and at last end generates non-polymorphic code,<br />
Haskell's using of dictionaries allows run-time polymorphism<br />
(explanation of run-time polymorphism? -what is this? a form of dynamic dispatch?).<br />
<br />
Moreover, Haskell type classes supports inheritance. Run-time<br />
polymorphism together with inheritance are often seen as OOP<br />
distinctive points, so during long time I considered type classes as a<br />
form of OOP implementation. But that's wrong! Haskell type classes<br />
build on different basis, so they are like C++ templates with added<br />
inheritance and run-time polymorphism! And this means that usage of<br />
type classes is different from using classes, with its own strong and<br />
weak points.<br />
<br />
<br />
== Type classes vs classes ==<br />
<br />
Here is a brief listing of differences between OOP classes and Haskell type classes<br />
<br />
=== Type classes are like interfaces/abstract classes, not classes itself ===<br />
<br />
There is no inheritance and data fields<br />
(so type classes are more like interfaces than classes)....<br />
<br />
<br />
For those more familiar with Java/C# rather than C++, type classes resemble interfaces more than the classes. In fact, the generics in those languages capture the notion of parametric polymorphism (but Haskell is a language that takes parametric polymorphism quite seriously, so you can expect a fair amount of type gymnastics when dealing with Haskell), so more precisely, type classes are like generic interfaces.<br />
<br />
Why interface, and not class? Mostly because type classes do not implement the methods themselves, they just guarantee that the actual types that instantiate the type class will implement specific methods. So the types are like classes in Java/C#.<br />
<br />
One added twist: type classes can decide to provide default implementation of some methods (using other methods). You would say, then they are sort of like abstract classes. Right. But at the same time, you cannot extend (inherit) multiple abstract classes, can you?<br />
<br />
So a type class is sort of like a contract: "any type that instantiates this type class will have the following functions defined on them..." but with the added advantage that you have type parameters built-in, so:<br />
<br />
<haskell><br />
class Eq a where<br />
(==) :: a -> a -> Bool<br />
(/=) :: a -> a -> Bool<br />
-- let's just implement one function in terms of the other<br />
x /= y = not (x == y) <br />
</haskell><br />
<br />
is, in a Java-like language:<br />
<br />
'''interface''' Eq<A> {<br />
'''boolean''' equal(A that);<br />
'''boolean''' notEqual(A that) { <br />
''// default, can be overriden''<br />
'''return''' !equal(that); <br />
} <br />
}<br />
<br />
And the "instance TypeClass ParticularInstance where ..." definition means "ParticularInstance implements TypeClass { ... }", now, multiple parameter type classes, of course, cannot be interpreted this way.<br />
<br />
<br />
=== Type can appear at any place in function signature ===<br />
Type can appear at any place in function signature: be any<br />
parameter, inside parameter, in a list (possibly empty), or in a result<br />
<br />
<haskell><br />
class C a where<br />
f :: a -> Int<br />
g :: Int -> a -> Int<br />
h :: Int -> (Int,a) -> Int<br />
i :: [a] -> Int<br />
j :: Int -> a<br />
new :: a<br />
</haskell><br />
<br />
It's even possible to define instance-specific constants (look at 'new').<br />
<br />
If function value is instance-specific, OOP programmer will use<br />
"static" method while with type classes you need to use fake<br />
parameter:<br />
<br />
<haskell><br />
class FixedSize a where<br />
sizeof :: a -> Int<br />
instance FixedSize Int8 where<br />
sizeof _ = 1<br />
instance FixedSize Int16 where<br />
sizeof _ = 2<br />
<br />
main = do print (sizeof (undefined::Int8))<br />
print (sizeof (undefined::Int16))<br />
</haskell><br />
<br />
<br />
=== Inheritance between interfaces ===<br />
Inheritance between interfaces (in "class" declaration) means<br />
inclusion of base class dictionaries in dictionary of subclass:<br />
<br />
<haskell><br />
class (Show s, Monad m s) => Stream m s where<br />
sClose :: s -> m ()<br />
</haskell><br />
<br />
means<br />
<br />
<haskell><br />
type StreamDictionary m s = (ShowDictionary s, MonadDictionary m s, s->m())<br />
</haskell><br />
<br />
There is upcasting mechanism, it just extracts dictionary of a base<br />
class from a dictionary tuple, so you can run a function that requires<br />
base class from a function that requires subclass:<br />
<br />
<haskell><br />
f :: (Stream m s) => s -> m String<br />
show :: (Show s) => s -> String<br />
f s = return (show s)<br />
</haskell><br />
<br />
But downcasting is absolutely impossible - there is no way to get<br />
subclass dictionary from a superclass one<br />
<br />
<br />
<br />
=== Inheritance between instances ===<br />
Inheritance between instances (in "instance" declaration) means<br />
that operations of some class can be executed via operations of other<br />
class, i.e. such declaration describe a way to compute dictionary of<br />
inherited class via functions from dictionary of base class:<br />
<br />
<haskell><br />
class Eq a where<br />
(==) :: a -> a -> Bool<br />
class Cmp a where<br />
cmp :: a -> a -> Ordering<br />
instance (Cmp a) => Eq a where<br />
a==b = cmp a b == EQ<br />
</haskell><br />
<br />
creates the following function:<br />
<br />
<haskell><br />
cmpDict2EqDict :: CmpDictionary a -> EqDictionary a<br />
cmpDict2EqDict (cmp) = (\a b -> cmp a b == EQ)<br />
</haskell><br />
<br />
This results in that any function that receives dictionary for Cmp class<br />
can call functions that require dictionary of Eq class<br />
<br />
<br />
=== Downcasting is a mission impossible ===<br />
<br />
Selection between instances is done at compile-time, based only on<br />
information present at the moment. So don't expect that more concrete<br />
instance will be selected just because you passed this concrete<br />
datatype to the function which accepts some general class:<br />
<br />
<haskell><br />
class Foo a where<br />
foo :: a -> String<br />
<br />
instance (Num a) => Foo a where<br />
foo _ = "Num"<br />
<br />
instance Foo Int where<br />
foo _ = "int"<br />
<br />
f :: (Num a) => a -> String<br />
f = foo<br />
<br />
main = do print (foo (1::Int))<br />
print (f (1::Int))<br />
</haskell><br />
<br />
Here, the first call will return "int", but second - only "Num".<br />
this can be easily justified by using dictionary-based translation<br />
as described above. After you've passed data to polymorphic procedure<br />
it's type is completely lost, there is only dictionary information, so<br />
instance for Int can't be applied. The only way to construct Foo<br />
dictionary is by calculating it from Num dictionary using the first<br />
instance.<br />
<br />
:<i>Remark: This isn't even a legal program unless you use the <hask>IncoherentInstances</hask> language extension. The error message:</i><br />
<br />
<haskell><br />
Overlapping instances for Foo a<br />
arising from a use of `foo' at /tmp/I.hs:17:4-6<br />
Matching instances:<br />
instance [overlap ok] (Num a) => Foo a<br />
-- Defined at /tmp/I.hs:10:9-24<br />
instance [overlap ok] Foo Int -- Defined at /tmp/I.hs:13:9-15<br />
(The choice depends on the instantiation of `a'<br />
To pick the first instance above, use -XIncoherentInstances <br />
when compiling the other instance declarations)<br />
</haskell><br />
:<i>Details: [http://haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#instance-overlap GHC User's Guide]</i><br />
<br />
=== There is only one dictionary per function call ===<br />
For "eqList :: (Eq a) => [a] -> [a] -> Bool" types of all elements<br />
in list must be the same, and types of both arguments must be the same<br />
too - there is only one dictionary and it know how to handle variables<br />
of only one concrete type!<br />
<br />
=== Existential variables is more like OOP objects ===<br />
Existential variables pack dictionary together with variable (looks<br />
very like the object concept!) so it's possible to create polymorphic<br />
containers (i.e. holding variables of different types). But<br />
downcasting is still impossible. Also, existentials still don't allow<br />
to mix variables of different types in a call to some polymorhic operation<br />
(their personal dictionaries still built for variables of one concrete type):<br />
<br />
<haskell><br />
data HasCmp = forall a. Cmp a => HasCmp a<br />
<br />
sorted :: [HasCmp] -> Ordering<br />
<br />
sorted [] = True<br />
sorted [_] = True<br />
sorted (HasCmp a : HasCmp b : xs) = a<=b && sorted (b:xs)<br />
</haskell><br />
<br />
This code will not work - a<=b can use nor 'a' neither 'b' dictionary.<br />
Even if orderings for apples and penguins are defined, we still don't have<br />
a method to compare penguins to apples!<br />
<br />
<br />
== Other opinions ==<br />
<br />
=== OO class always corresponds to a haskell class + a related haskell existential (John Meacham) ===<br />
<br />
> Roughly Haskell type classes correspond to parameterized abstract<br />
> classes in C++ (i.e. class templates with virtual functions <br />
> representing the operations). Instance declarations correspond to<br />
> derivation and implementations of those parameterized classes.<br />
<br />
There is a major difference though, in C++ (or java, or sather, or c#,<br />
etc.) the dictionary is always attached to the value, the actual class<br />
data type you pass around. In Haskell, the dictionary is passed<br />
separately and the appropriate one is inferred by the type system. C++<br />
doesn't infer, it just assumes everything will be carrying around its<br />
dictionary with it.<br />
<br />
This makes Haskell classes significantly more powerful in many ways.<br />
<br />
<haskell><br />
class Num a where<br />
(+) :: a -> a -> a<br />
</haskell><br />
<br />
is impossible to express in OO classes: since both arguments to +<br />
necessarily carry their dictionaries with them, there is no way to<br />
statically guarantee they have the same one. Haskell will pass a single<br />
dictionary that is shared by both types so it can handle this just fine.<br />
<br />
In haskell you can do<br />
<br />
<haskell><br />
class Monoid a where<br />
mempty :: a<br />
</haskell><br />
<br />
In OOP, this cannot be done because where does the dictionary come from?<br />
Since dictionaries are always attached to a concrete class, every method<br />
must take at least one argument of the class type (in fact, exactly one,<br />
as I'll show below). In Haskell again, this is not a problem since the<br />
dictionary is passed in by the consumer of 'mempty' - mempty need not<br />
conjure one out of thin air.<br />
<br />
In fact, OO classes can only express single parameter type classes where<br />
the type argument appears exactly once in strictly covariant position.<br />
In particular, it is pretty much always the first argument and often<br />
(but not always) named 'self' or 'this'.<br />
<br />
<haskell><br />
class HasSize a where<br />
getSize :: a -> Int<br />
</haskell><br />
<br />
can be expressed in OO, 'a' appears only once, as its first argument.<br />
<br />
Now, another thing OO classes can do is they give you the ability to<br />
create existential collections (?) of objects. As in, you can have a<br />
list of things that have a size. In Haskell, the ability to do this is<br />
independent of the class (which is why Haskell classes can be more<br />
powerful) and is appropriately named existential types.<br />
<br />
<haskell><br />
data Sized = exists a . HasSize a => Sized a <br />
</haskell><br />
<br />
What does this give you? You can now create a list of things that have a<br />
size [Sized] yay!<br />
<br />
And you can declare an instance for Sized, so you can use all your<br />
methods on it.<br />
<br />
<haskell><br />
instance HasSize Sized where<br />
getSize (Sized a) = getSize a<br />
</haskell><br />
<br />
An existential, like Sized, is a value that is passed around with its<br />
dictionary in tow, as in, it is an OO class! I think this is where<br />
people get confused when comparing OO classes to Haskell classes. _There<br />
is no way to do so without bringing existentials into play_. OO classes<br />
are inherently existential in nature.<br />
<br />
So, an OO abstract class declaration declares the equivalent of 3 things<br />
in Haskell: a class to establish the methods, an existential type to<br />
carry the values about, and an instance of the class for the existential<br />
type.<br />
<br />
An OO concrete class declares all of the above plus a data declaration<br />
for some concrete representation.<br />
<br />
OO classes can be perfectly (even down to the runtime representation!)<br />
emulated in Haskell, but not vice versa. Since OO languages tie class<br />
declarations to existentials, they are limited to only the intersection<br />
of their capabilities, because Haskell has separate concepts for them;<br />
each is independently much much more powerful.<br />
<br />
<haskell><br />
data CanApply = exists a b . CanApply (a -> b) a (b -> a)<br />
</haskell><br />
<br />
is an example of something that cannot be expressed in OO, existentials<br />
are limited to having exactly a single value since they are tied to a<br />
single dictionary.<br />
<br />
<haskell><br />
class Num a where<br />
(+) :: a -> a -> a<br />
zero :: a<br />
negate :: a -> a<br />
</haskell><br />
<br />
cannot be expressed in OO, because there is no way to pass in the same<br />
dicionary for two elements, or for a returning value to conjure up a<br />
dictionary out of thin air. (If you are not convinced, try writing a<br />
'Number' existential and making it an instance of Num and it will be<br />
clear why it is not possible.)<br />
<br />
negate is an interesting one - there is no technical reason it cannot be<br />
implemented in OO languages, but none seem to actually support it.<br />
<br />
So, when comparing, remember an OO class always corresponds to a Haskell<br />
class + a related Haskell existential.<br />
<br />
Incidentally, an extension I am working on is to allow<br />
<br />
<haskell><br />
data Sized = exists a . HasSize a => Sized a <br />
deriving(HasSize)<br />
</haskell><br />
<br />
which would have the obvious interpretation. Obviously it would only work<br />
under the same limitations as OO classes have, but it would be a simple<br />
way for haskell programs to declare OO style classes if they so choose.<br />
<br />
(Actually, it is still signifigantly more powerful than OO classes since<br />
you can derive many instances, and even declare your own for classes<br />
that don't meet the OO constraints. Also, your single class argument need<br />
not appear as the first one. It can appear in any strictly covariant<br />
position, and it can occur as often as you want in contravariant ones!)<br />
<br />
=== Type classes correspond to parameterized abstract classes (Gabriel Dos Reis) ===<br />
<br />
| > Roughly Haskell type classes correspond to parameterized abstract<br />
| > classes in C++ (i.e. class templates with virtual functions <br />
| > representing the operations). Instance declarations correspond to<br />
| > derivation and implementations of those parameterized classes.<br />
| <br />
| There is a major difference though, in C++ (or java, or sather, or c#,<br />
| etc..) the dictionary is always attached to the value, the actual class<br />
| data type you pass around.<br />
<br />
I suspect that most of the confusion come from the fact that people<br />
believe just because virtual functions are attached to objects, <br />
they cannot attach them to operations outside classes. That, to my<br />
surprise, hints at a deeper misappreciation of both type classes and<br />
so-called "OO" technology. Type classes are more OO than one might<br />
realize. <br />
<br />
The dictionary can be attached to the operations (not just to the values) by<br />
using objects local to functions (which sort of matierialize the<br />
dictionary). Consider<br />
<br />
// Abstract class for a collection of classes that implement<br />
// the "Num" mathematical structure<br />
template<typename T><br />
struct Num {<br />
virtual T add(T, T) const = 0;<br />
};<br />
<br />
// Every type must specialize this class template to assert<br />
// membership to the "Num" structure. <br />
template<typename T> struct Num_instance;<br />
<br />
// The operation "+" is defined for any type that belongs to "Num".<br />
// Notice, membership is asserted aby specializing Num_instance<>.<br />
template<typename T><br />
T operator+(T lhs, T rhs)<br />
{<br />
const Num_instance<T> instance; <br />
return instance.add(lhs, rhs);<br />
}<br />
<br />
// "Foo" is in "Num"<br />
struct Num_instance<Foo> : Num<Foo> {<br />
Foo add(Foo a, Foo b) const { ... }<br />
};<br />
<br />
<br />
The key here is in the definition of operator+ which is just a formal<br />
name for the real operation done by instance.add().<br />
<br />
I appreciate that inferring and building the dictionary (represented<br />
here by the "instance" local to operator+<T>) is done automatically by<br />
the Haskell type system.<br />
That is one of the reasons why the type class notation is a nice sugar.<br />
However, that should not distract from its deerper OO semantics.<br />
<br />
<br />
[...]<br />
<br />
| in haskell you can do<br />
| <br />
| class Monoid a where<br />
| mempty :: a<br />
| <br />
| in OOP, this cannot be done because where does the dicionary come from?<br />
<br />
See above. I believe a key in my suggestion was "parameterized<br />
abstract classes", not just "abstract classes".<br />
<br />
<br />
<br />
== Haskell emulation of OOP inheritance with record extension ==<br />
<br />
Brian Hulley provided us the code that shows how OOP inheritance can be<br />
emulated in Haskell. His translation method supports data fields<br />
inheritance, although don't supports downcasting.<br />
<br />
> although i mentioned not only pluses but also drawbacks of type<br />
> classes: lack of record extension mechanisms (such at that implemented<br />
> in O'Haskell) and therefore inability to reuse operation<br />
> implementation in an derived data type...<br />
<br />
You can reuse ops in a derived data type but it involves a tremendous amount <br />
of boilerplate. Essentially, you just use the type classes to simulate <br />
extendable records by having a method in each class that accesses the <br />
fixed-length record corresponding to that particular C++ class.<br />
<br />
Here is an example (apologies for the length!) which shows a super class <br />
function being overridden in a derived class and a derived class method <br />
(B::Extra) making use of something implemented in the super class:<br />
<br />
<haskell><br />
module Main where<br />
<br />
{- Haskell translation of the following C++<br />
<br />
class A {<br />
public:<br />
String s;<br />
Int i;<br />
<br />
A(String s, Int i) s(s), i(i){}<br />
<br />
virtual void Display(){<br />
printf("A %s %d\n", s.c_str(), i);<br />
}<br />
<br />
virtual Int Reuse(){<br />
return i * 100;<br />
}<br />
};<br />
<br />
<br />
class B: public A{<br />
public:<br />
Char c;<br />
<br />
B(String s, Int i, Char c) : A(s, i), c(c){}<br />
<br />
virtual void Display(){<br />
printf("B %s %d %c", s.c_str(), i, c);<br />
}<br />
<br />
virtual void Extra(){<br />
printf("B Extra %d\n", Reuse());<br />
}<br />
<br />
};<br />
<br />
-}<br />
<br />
data A = A<br />
{ _A_s :: String<br />
, _A_i :: Int<br />
}<br />
<br />
-- This could do arg checking etc<br />
constructA :: String -> Int -> A<br />
constructA = A<br />
<br />
<br />
class ClassA a where<br />
getA :: a -> A<br />
<br />
display :: a -> IO ()<br />
display a = do<br />
let<br />
A{_A_s = s, _A_i = i} = getA a<br />
putStrLn $ "A " ++ s ++ show i<br />
<br />
reuse :: a -> Int<br />
reuse a = _A_i (getA a) * 100<br />
<br />
<br />
data WrapA = forall a. ClassA a => WrapA a<br />
<br />
instance ClassA WrapA where<br />
getA (WrapA a) = getA a<br />
display (WrapA a) = display a<br />
reuse (WrapA a) = reuse a<br />
<br />
instance ClassA A where<br />
getA = id<br />
<br />
<br />
data B = B { _B_A :: A, _B_c :: Char }<br />
<br />
<br />
constructB :: String -> Int -> Char -> B<br />
constructB s i c = B {_B_A = constructA s i, _B_c = c}<br />
<br />
class ClassA b => ClassB b where<br />
getB :: b -> B<br />
<br />
extra :: b -> IO ()<br />
extra b = do<br />
putStrLn $ "B Extra " ++ show (reuse b)<br />
<br />
data WrapB = forall b. ClassB b => WrapB b<br />
<br />
instance ClassB WrapB where<br />
getB (WrapB b) = getB b<br />
extra (WrapB b) = extra b<br />
<br />
instance ClassA WrapB where<br />
getA (WrapB b) = getA b<br />
display (WrapB b) = display b<br />
reuse (WrapB b) = reuse b<br />
<br />
instance ClassB B where<br />
getB = id<br />
<br />
instance ClassA B where<br />
getA = _B_A<br />
<br />
-- override the base class version<br />
display b = putStrLn $<br />
"B " ++ _A_s (getA b)<br />
++ show (_A_i (getA b))<br />
++ [_B_c (getB b)]<br />
<br />
<br />
main :: IO ()<br />
main = do<br />
let<br />
a = constructA "a" 0<br />
b = constructB "b" 1 '*'<br />
<br />
col = [WrapA a, WrapA b]<br />
<br />
mapM_ display col<br />
putStrLn ""<br />
mapM_ (putStrLn . show . reuse) col<br />
putStrLn ""<br />
extra b<br />
<br />
{- Output:<br />
<br />
> ghc -fglasgow-exts --make Main<br />
> main<br />
A a0<br />
B b1*<br />
<br />
0<br />
100<br />
<br />
B Extra 100<br />
<br />
><br />
-}<br />
</haskell><br />
<br />
(If the "caseless underscore" Haskell' ticket is accepted the leading <br />
underscores would have to be replaced by something like "_f" ie _A_s ---> <br />
_fA_s etc)<br />
<br />
<br />
<br />
== Type class system extensions ==<br />
<br />
Brief list of extensions, their abbreviated names and compatibility level<br />
<br />
* Constructor classes (Haskell'98)<br />
* MPTC: multi-parameter type classes (Hugs/GHC extension)<br />
* FD: functional dependencies (Hugs/GHC extension)<br />
* AT: associated types (GHC 6.6 only)<br />
* Overlapped, undecidable and incoherent instances (Hugs/GHC extension)<br />
<br />
<br />
== Literature ==<br />
<br />
The paper that at first time introduced type classes and their implementation<br />
using dictionaries was Philip Wadler and Stephen Blott "How to make ad-hoc polymorphism less ad-hoc" (http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz)<br />
<br />
You can find more papers on the [http://haskell.org/haskellwiki/Research_papers/Type_systems#Type_classes Type classes] page.<br />
<br />
I thanks Ralf Lammel and Klaus Ostermann for their paper<br />
"Software Extension and Integration with Type Classes" (http://homepages.cwi.nl/~ralf/gpce06/) which prompts me to start thinking about differences between OOP and type classes instead of their similarities<br />
<br />
[[Category:Tutorials]]</div>JeffFosterhttps://wiki.haskell.org/index.php?title=GHC/GHCi_debugger&diff=29903GHC/GHCi debugger2009-09-02T06:14:25Z<p>JeffFoster: Update link to user docs to something that works.</p>
<hr />
<div>[[Category:GHC|GHCi debugger]]<br />
The GHCi Debugger project extends ghci with basic debugging capabilities. See the GHC user docs for more info.<br />
<br />
== Current status == <br />
The debugger is available in the released [http://www.haskell.org/ghc/download_ghc_681.html GHC 6.8.1]. Full documentation in the [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html user docs].</div>JeffFoster