https://wiki.haskell.org/api.php?action=feedcontributions&user=RoelVanDijk&feedformat=atomHaskellWiki - User contributions [en]2021-09-28T07:25:19ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=ZuriHac2014/Projects&diff=58241ZuriHac2014/Projects2014-06-01T14:07:55Z<p>RoelVanDijk: </p>
<hr />
<div>These are some of the projects that ZuriHac 2014 [[ZuriHac2014/Attendees|attendees]] will be working on:<br />
<br />
=Aeson=<br />
<br />
See: http://hackage.haskell.org/package/aeson<br />
<br />
* Bas van Dijk (Faster JSON encoder)<br />
<br />
=Scion / Lambdachine=<br />
<br />
* Thomas Schilling<br />
<br />
=Hakyll=<br />
<br />
See: http://jaspervdj.be/hakyll/<br />
<br />
* Jasper van der Jeugt<br />
* David Wagner<br />
<br />
=Haskell: the Gathering=<br />
<br />
Implementation of Magic: the Gathering in Haskell. We will work on [https://github.com/MedeaMelana/Magic the rules engine], [https://github.com/MedeaMelana/Magic/tree/master/Magic-Cards/src/Magic card implementations] (both in Haskell) and [https://github.com/q42jaap/magic-client the web client] (TypeScript/HTML). Help is welcome in all three areas.<br />
<br />
* Martijn van Steenbergen<br />
<br />
=T-Digest=<br />
<br />
Persistent implementation of the T-Digest (https://github.com/tdunning/t-digest) quantile estimation data structure, for use in ekg.<br />
<br />
* Johan Tibell<br />
<br />
=Nomyx=<br />
<br />
Nomyx is a game where you can change the rules while playing: http://www.nomyx.net<br />
<br />
* Corentin Dupont (I'll work on new features and [http://www.github.com/cdupont/Nomyx/issues?state=open bugs] . Help/advices are welcome :))<br />
<br />
=Snap=<br />
<br />
See: http://snapframework.com/<br />
<br />
* Alfredo Di Napoli - I have in mind a couple of interesting features I would like to see in snap.<br />
<br />
=Hackage=<br />
<br />
See: http://hackage.haskell.org/<br />
<br />
* Ian Ross (tags interface)<br />
* Alp Mestanogullari (most likely a nice statistics page)<br />
<br />
=GHC bug squashing=<br />
<br />
I plan to fix a few random GHC bugs and I’m more than happy to guide GHC-newbies in doing the same. Planning and coordination will happen at https://ghc.haskell.org/trac/ghc/wiki/ZuriHac2014. I started to collect some suitable tickets, feel free to add some.<br />
<br />
* Joachim Breitner<br />
* Lorenzo Tabacchini<br />
<br />
=Oauth-provider=<br />
<br />
See: http://github.com/gseitz/oauth-provider<br />
<br />
* Gerolf Seitz (I would like to have a RFC / code-review on oauth-provider)<br />
<br />
=Math Symbols in Diagrams=<br />
<br />
I'd like to be able to label diagrams with mats symbols and fonts: http://projects.haskell.org/diagrams/. There has been some discussion of this on #diagrams and I need to write up an approach. NB I have used diagrams a lot but never hacked on the package itself.<br />
<br />
* Dominic Steinitz<br />
* David Wagner<br />
<br />
=Propellor=<br />
<br />
See: http://hackage.haskell.org/package/propellor<br />
<br />
* David Wagner (I would like to add [http://mmonit.com/monit/ monit] support to propellor).<br />
<br />
=Rest=<br />
<br />
We have recently open sourced our [https://github.com/silkapp/rest rest framework] which Erik Hesselink gave a presentation about at last years ZuriHac. It provides a declarative way to define REST resources (rest-core) which can be used to run the api on different web servers (rest-happstack, rest-snap) and to automatically generate clients for different languages along with documentation and usage examples (rest-gen). We want to write introductory materials to get people started. We'd appreciate help and we'd be happy to sit down with anyone wanting to get started with rest.<br />
<br />
* Adam Bergmark<br />
* Erik Hesselink<br />
* Sebastiaan Visser<br />
<br />
Project ideas:<br />
<br />
* Write tutorials based on the rest-example blog application<br />
* Refactor the rest-gen haskell client generation to use haskell-src-exts<br />
* Write a test-framework that runs an api and uses its generated client<br />
<br />
= Erlang Interpreter in Haskell=<br />
<br />
This is my learning project for Haskell, and since I come from Erlang background I have chosen to combine both things into one.<br />
<br />
* Gleb Peregud<br />
* Felipe Zapata<br />
<br />
= LGtk: GUI framework in Haskell=<br />
<br />
See [http://lgtk.wordpress.com/ http://lgtk.wordpress.com/] and [http://www.haskell.org/haskellwiki/LGtk http://www.haskell.org/haskellwiki/LGtk].<br />
I would like to work on a browser backend with GHCJS and improving documentation (writing a tutorial especially).<br />
<br />
* Péter Diviánszky<br />
<br />
= LambdaCube 3D=<br />
[http://lambdacube3d.wordpress.com/ LambdaCube 3D] is a domain specific language and library that makes it possible to program GPUs in a purely functional style.<br />
During ZuriHac I'll work on a WebGL backend.<br />
<br />
* Csaba Hruska<br />
<br />
= extensible-effects =<br />
<br />
Revise the package's API and prepare the 2.0 version.<br />
<br />
WIP is at https://github.com/feuerbach/extensible-effects<br />
<br />
* Roman Cheplyaka<br />
<br />
= complexity =<br />
<br />
[http://hackage.haskell.org/package/complexity Complexity] is a tool to measure the emprical complexity of functions. During Zurihac we want to rewrite complexity so that it makes use of the excellent Criterion package. We also want to rewrite the reporting part. Perhaps not depend on any GUI toolkits but instead generate a static HTML report.<br />
<br />
* Roel van Dijk<br />
* Tim Schwarte</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Unicode-symbols&diff=55865Unicode-symbols2013-05-07T13:19:39Z<p>RoelVanDijk: /* New symbol ideas */</p>
<hr />
<div>[[Category:Packages]]<br />
<br />
== Overview ==<br />
<br />
An overview of the packages that provide Unicode symbols. <br />
<br />
Naming: A package '''<tt>X-unicode-symbols</tt>''' defines new symbols for functions and operators from the package '''<tt>X</tt>'''.<br />
<br />
All symbols are documented with their actual definition and information regarding their Unicode code point. They should be completely interchangeable with their definitions.<br />
<br />
Alternatives for existing operators have the same fixity. New operators will have a suitable fixity defined.<br />
<br />
==== UnicodeSyntax ====<br />
<br />
GHC offers the [http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#unicode-syntax UnicodeSyntax] language extension. If you decide to use Unicode in your Haskell source then this extension can greatly improve how it looks.<br />
<br />
Simply put the following above a module to enable unicode syntax:<br />
{-# LANGUAGE UnicodeSyntax #-}<br />
<br />
== base-unicode-symbols ==<br />
<br />
Extra symbols for the [http://hackage.haskell.org/package/base base] package.<br />
<br />
API docs: http://hackage.haskell.org/package/base-unicode-symbols<br />
github: https://github.com/roelvandijk/base-unicode-symbols<br />
checkout: git clone git://github.com/roelvandijk/base-unicode-symbols.git<br />
<br />
==== Problematic symbols ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Original<br />
! Symbol<br />
! Code point<br />
! Name<br />
|-<br />
| not<br />
| &#xAC;<br />
| U+AC<br />
| NOT SIGN<br />
|-<br />
| lambda<br />
| &#x3BB;<br />
| U+03BB<br />
| GREEK SMALL LETTER LAMDA<br />
|}<br />
The problem with the NOT symbol is that you would like to use it as an unary prefix operator:<br />
&not;(&not;x) &equiv; x<br />
Unfortunately this is not valid Haskell. The following is:<br />
(&not;)((&not;)x) &equiv; x<br />
But you can hardly call that an improvement over the simple:<br />
not (not x) &equiv; x<br />
<br />
The problem with the LAMBDA symbol is that it is classified as an alphabetic character, so it can be used as part of a name. See the [http://hackage.haskell.org/trac/ghc/ticket/1102 discussion for GHC].<br />
<br />
==== New symbol ideas ====<br />
(''please add your own'')<br />
<br />
I'm thinking of adding the following symbol as another alternative for (*).<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Original<br />
! Symbol<br />
! Code point<br />
! Name<br />
|-<br />
| (*)<br />
| &#xD7;<br />
| U+D7<br />
| MULTIPLICATION SIGN<br />
|}<br />
<br />
2 * 3 &equiv; 6<br />
2 &#x22C5; 3 &equiv; 6<br />
2 &#xD7; 3 &equiv; 6<br />
<br />
A disadvantage of this symbol is its similarity to the letter x:<br />
sqr x = x &#xD7; x<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Original<br />
! Symbol<br />
! Code point<br />
! Name<br />
|-<br />
| Bool<br />
| &#x1D539;<br />
| U+1D539<br />
| MATHEMATICAL DOUBLE-STRUCK CAPITAL B<br />
|}<br />
<br />
This idea is an extension of<br />
<br />
type &#x2124; = Integer<br />
<br />
and<br />
<br />
type &#x211A; = Ratio &#x2124;<br />
<br />
The advantage is that it looks nice and that it is a logical extension of &#x2124;, &#x211A; and &#x211D;. The disadvantage is that there is no documented prior use of this character to denote boolean values. This could be detrimental to the readability of code.<br />
<br />
Example:<br />
<br />
(&#x2227;) &#x2237; &#x1D539; &#x2192; &#x1D539; &#x2192; &#x1D539;<br />
<br />
== containers-unicode-symbols ==<br />
<br />
Extra symbols for the [http://hackage.haskell.org/package/containers containers] package.<br />
<br />
API docs: http://hackage.haskell.org/package/containers-unicode-symbols<br />
github: https://github.com/roelvandijk/containers-unicode-symbols<br />
checkout: git clone git://github.com/roelvandijk/containers-unicode-symbols.git <br />
<br />
==== New symbol ideas ==== <br />
(''please add your own'')<br />
<br />
== Input methods ==<br />
<br />
These symbols are all very nice but how do you type them?<br />
<br />
Wikipedia has a helpful article: http://en.wikipedia.org/wiki/Unicode_input<br />
<br />
(''please add info for other editors'')<br />
<br />
=== Emacs ===<br />
<br />
'''Direct'''<br />
<br />
Enter symbols directly: <tt>[http://www.gnu.org/software/emacs/manual/html_node/emacs/International-Chars.html C-x 8 RET]</tt> (<tt>ucs-insert</tt>), then type either the character's name or its hexadecimal code point.<br />
<br />
'''TeX input method'''<br />
<br />
The TeX input method, invoked with <tt>M-x set-input-method</tt> and entering <tt>TeX</tt> allows you to enter Unicode characters by typing in TeX-like sequences. For example, typing <tt>\lambda</tt> inserts a λ.<br />
<br />
This is probably the most convenient input method for casual use.<br />
<br />
A list of available sequences may be viewed with <tt>M-x describe-input-method</tt><br />
<br />
'''Custom input method'''<br />
<br />
I wrote my own input method:<br />
<br />
github: https://github.com/roelvandijk/emacs-haskell-unicode-input-method<br />
checkout: git clone git://github.com/roelvandijk/emacs-haskell-unicode-input-method.git<br />
<br />
To automically load in haskell-mode put the following code in your .emacs file:<br />
(require 'haskell-unicode-input-method)<br />
(add-hook 'haskell-mode-hook <br />
(lambda () (set-input-method "haskell-unicode")))<br />
<br />
Make sure the directory containing the .elisp file is in your load-path, for example:<br />
(add-to-list 'load-path "~/.elisp/emacs-haskell-unicode-input-method")<br />
<br />
To manually enable use <tt>M-x set-input-method</tt> or <tt>C-x RET C-\</tt> with <tt>haskell-unicode</tt>. Note that the elisp file must be evaluated for this to work.<br />
<br />
Now you can simply type <tt>-></tt> and it is immediately replaced with &rarr;. Use <tt>C-\</tt> to toggle the input method. To see a table of all key sequences use <tt>M-x describe-input-method haskell-unicode</tt>. A sequence like <= is ambiguous and can mean either <tt>&lArr;</tt> or <tt>&le;</tt>. Typing it presents you with a choice. Type 1 or 2 to select an option or keep typing to use the default option.<br />
<br />
If you don't like the highlighting of partially matching tokens you can turn it off:<br />
<br />
(setq input-method-highlight-flag nil)<br />
<br />
'''Abbrev mode'''<br />
<br />
The [http://www.gnu.org/software/emacs/manual/html_node/emacs/Abbrevs.html Abbrev mode] is not suitable since it only deals with ''words'', not ''operators''.<br />
<br />
'''Agda'''<br />
<br />
Use Agda's [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Docs.UnicodeInput input method].<br />
<br />
=== Vim ===<br />
<br />
(''real Vim users might want to expand this section'')<br />
<br />
'''Direct'''<br />
<br />
* Decimal value: type '''C-Vnnn''' where 0 &le; nnn &le; 255.<br />
* Octal value: type '''C-VOnnn''' or '''C-Vonnn''' where 0 &le; nnn &le; 377.<br />
* Hex value: type '''C-VXnn''' or '''C-Vxnn''' where 0 &le; nn &le; FF.<br />
* Hex value for BMP codepoints: type '''C-Vunnnn''' where 0 &le; nnnn &le; FFFF.<br />
* Hex value for any codepoint: type '''C-VUnnnnnnnn''' where 0 &le; nnnnnnnn &le; FFFFFFFF.<br />
<br />
'''Automatic Unicode Transformation'''<br />
<br />
Furthermore, there is a Haskell file type plugin called [https://github.com/frerich/unicode-haskell unicode-haskell] which automatically transforms ASCII character sequences (e.g. -> and many others) to Unicode when loading Haskell source code - and the data is converted back when saving. That way, the source code remains plain ASCII on disk but uses nice Unicode characters in vim/gvim. Furthermore, the plugin will automatically replace ASCII sequences with their Unicode equivalents as you type.<br />
<br />
The Vim conceal definitions in haskellmode-vim pleasantly mask most of usual symbols with the unicode equivalent but have no effect on the actual source code (in my experience, this is much faster than unicode-haskell and it's much easier to edit). While in normal mode, the concealed characters on the current line will be displayed as ASCII. In insert mode and on lines other than the current one in normal mode, Unicode characters will be displayed.<br />
<br />
=== SciTE ===<br />
<br />
See [[Tips_for_using_SciTE_with_Haskell]]<br />
<br />
=== Sublime Text 2 ===<br />
<br />
Syntax highlighting for the GHC unicode syntax is not supported in the default configuration as of version 2.0.1. However the following patch, when applied to <code>Packages/Haskell/Haskell.tmLanguage</code>, does enable this: https://gist.github.com/3744568<br />
<br />
Insert the following snippet into user key bindings to conveniently type unicode operators in Haskell code: https://gist.github.com/3766192 . For example, typing "->" will automatically insert "→".<br />
<br />
=== System wide ===<br />
<br />
'''m17n input methods'''<br />
<br />
A set of input methods has been written by Urs Holzer for the [http://www.m17n.org m17n] library. The main goal of Urs is to build input methods for mathematical characters. However, most of the symbols used in the *-unicode-symbols packages can be written using Urs's methods. More information is available at [http://www.andonyar.com/rec/2008-03/mathinput/ Input Methods for Mathematics] page. For most Linux distributions, just download a [http://www.andonyar.com/rec/2008-03/mathinput/methods.tar.gz tarball], extract *.mim files to /usr/share/m17n and enable iBus for input methods.<br />
<br />
== Fonts ==<br />
<br />
The following free fonts have good Unicode coverage:<br />
<br />
* [http://www.gnome.org/fonts/ Bitstream Vera Font Family]<br />
* [http://dejavu-fonts.org/wiki/Main_Page DejaVu Font Family]<br />
* [http://linuxlibertine.sourceforge.net/ Linux Libertine Font]<br />
* [https://www.redhat.com/promo/fonts/ RedHat Liberation Fonts]</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=DHD_UHac/Projects&diff=45351DHD UHac/Projects2012-04-21T08:02:41Z<p>RoelVanDijk: /* Projects */ Added dimensional-tf-parser project</p>
<hr />
<div>A big part of hackathons is working on projects together (in person, not online!). This page documents the projects at UHac.<br />
<br />
If you want to suggest a project, add a subsection under [[#Projects|Projects]].<br />
<br />
== Sharing code ==<br />
<br />
If you need a place to host a project so that others can help with it, there are many different options.<br />
<br />
* [http://github.com GitHub] is a popular social hosting service users of [http://git-scm.com/ git]<br />
* [http://patch-tag.com/ Patch-Tag] is a similar service for [http://darcs.net/ darcs].<br />
* The [http://community.haskell.org/admin/ Haskell.org community server] is also available. Be sure to apply for an account first, since it may take some time.<br />
<br />
== Projects ==<br />
<br />
Below are the projects potentially being undertaken at UHac.<br />
<br />
# You can add your own project using the template found in the wiki source.<br />
# You can add yourself to a project's list of interesting parties.<br />
<br />
=== GHC Generics ===<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
* Feel free to join! Also if you just have ideas of things that should work, or want to understand generics better<br />
<br />
Plans:<br />
* Implement deriving of <code>Generic1</code><br />
* Write a description of other GP libs in [http://www.haskell.org/haskellwiki/Generics the Haskell wiki]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5884 #5884]<br />
* Fix [http://hackage.haskell.org/trac/ghc/ticket/5939 #5939]<br />
* Think about [http://hackage.haskell.org/trac/ghc/ticket/5936 #5936]<br />
* Think harder about [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul using data kinds]<br />
<br />
=== Standard algorithms ===<br />
<br />
Objective point of this project is to implement or improve<br />
some standard algorithms like suffix arrays, z-function,<br />
cartesian trees, dijkstra algorithms which lack in standard library.<br />
<br />
Interested:<br />
* Victor Denisov<br />
<br />
Links:<br />
* https://github.com/haskellization/algorithms/wiki<br />
<br />
<br />
=== regex-applicative ===<br />
<br />
To learn about the project, see [https://github.com/feuerbach/regex-applicative/blob/master/README.md the README]. There will also be [http://www.haskell.org/haskellwiki/DHD_UHac/DHD_Program#regex-applicative a short talk] about it on the first day.<br />
<br />
The main challenge at the moment is to achieve decent performance.<br />
<br />
Interested:<br />
* Roman Cheplyaka<br />
<br />
<br />
=== Kind-polymorphic Typeable ===<br />
<br />
Implement [http://hackage.haskell.org/trac/ghc/wiki/GhcKinds/PolyTypeable the new kind-polymorphic Typeable] in GHC.<br />
<br />
Interested:<br />
* José Pedro Magalhães<br />
<br />
=== Parser for physical units and quantities ===<br />
<br />
Write a parser for the dimensional-tf package.<br />
<br />
Current status is a parser which parses physical units to a small expression language. The parsed units are normalised to the 7 base SI dimensions.<br />
<br />
The important part that doesn't work yet is to translate these expressions to Units and Quantities as defined by the dimensional-tf package.<br />
<br />
Interested:<br />
* Roel van Dijk<br />
<br />
Links:<br />
* https://github.com/roelvandijk/dimensional-tf-parser<br />
* http://hackage.haskell.org/package/dimensional-tf<br />
* https://github.com/bjornbm/dimensional-tf<br />
<br />
<br />
<!-- Copy this template<br />
=== Project Name ===<br />
<br />
I am a project. I am proud. I am Haskell.<br />
<br />
Interested:<br />
* Hacker 1<br />
* Hacker 2<br />
<br />
Links:<br />
* Repository<br />
* Hackage package<br />
* Blog posts<br />
--></div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=DHD_UHac/Attendees&diff=45241DHD UHac/Attendees2012-04-13T21:07:00Z<p>RoelVanDijk: Added myself</p>
<hr />
<div>This is a list of attendees for [[DHD_UHac|DHD >>= UHac]].<br />
<br />
If you have [[DHD_UHac/Register|registered]], please consider adding yourself to the list. Your contact and travel information may help with coordination between participants.<br />
<br />
If you live around Utrecht or plan to commute from home each day, you may put "Local" for accommodation.<br />
<br />
{| class="wikitable"<br />
! IRC Nickname<br />
! Real Name (Affl)<br />
! Mobile #<br />
! Arrive<br />
! Depart<br />
! Accommodation<br />
|-<br />
| leather<br />
| Sean Leather (UU)<br />
| +31616158163<br />
|<br />
|<br />
| Local<br />
|-<br />
| norm2782<br />
| Jurriën Stutterheim (UU)<br />
| +31642392944<br />
|<br />
|<br />
| Local<br />
|-<br />
| ruud<br />
| Ruud Koot (UU)<br />
| +31623024223<br />
|<br />
|<br />
| Local<br />
|-<br />
| kosmikus<br />
| Andres Löh (Well-Typed LLP)<br />
|<br />
| probably Fri morning<br />
| probably Mon morning<br />
| Hotel Oorsprongpark<br />
|-<br />
| sol<br />
| Simon Hengel<br />
| +4917661064074<br />
| Wednesday<br />
| Monday<br />
| [http://www.bedandbreakfast-kilim.com/ Kilim Bed and Breakfast]<br />
|-<br />
| dreixel<br />
| José Pedro Magalhães (UU)<br />
| +31650459029<br />
|<br />
|<br />
| Local<br />
|-<br />
| marczoid<br />
| Marc van Zee (UU)<br />
| +31633610518<br />
|<br />
|<br />
| Local<br />
|-<br />
| paba<br />
| Patrick Bahr (University of Copenhagen)<br />
|<br />
|<br />
|<br />
| Local<br />
|-<br />
| toothbrush<br />
| Paul van der Walt (UU)<br />
| +31614681351<br />
|<br />
|<br />
| Local<br />
|-<br />
| spockz<br />
| Alessandro Vermeulen (UU)<br />
| +31646165747<br />
|<br />
|<br />
| Local<br />
|-<br />
| wlad<br />
| Vlad Hanciuta<br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| gcollins<br />
| Gregory Collins (Google)<br />
| +41 79 441 6832<br />
|<br />
|<br />
| Karel V Hotel<br />
|-<br />
| <br />
| Pascal Hof<br />
| <br />
|<br />
|<br />
| <br />
|-<br />
| jaspervdj<br />
| Jasper Van der Jeugt<br />
| +32 476 26 48 47<br />
|<br />
|<br />
| Couchsurfing<br />
|-<br />
| cameleon<br />
| Erik Hesselink<br />
| +31 6 50 994 887<br />
|<br />
|<br />
| Local<br />
|-<br />
| sjoerd_visscher<br />
| Sjoerd Visscher<br />
| +31 6 1508 4368<br />
|<br />
|<br />
| Local<br />
|-<br />
| mklinik<br />
| Markus Klinik<br />
| +4917666101511<br />
| Wednesday<br />
| Sunday<br />
|<br />
|-<br />
| <br />
| Jurriaan Hage<br />
| +31 611191976<br />
| <br />
| <br />
| Local<br />
|-<br />
| ncs<br />
| Nikos Savvidis (UU)<br />
| +31644321424<br />
|<br />
|<br />
| Local<br />
|-<br />
| <br />
| Henk-Jan van Tuyl<br />
| <br />
|<br />
|<br />
| Local (travelling from Rotterdam, DHD only)<br />
|-<br />
| sfvisser<br />
| Sebastiaan Visser<br />
| +31624828951<br />
|<br />
|<br />
| Local<br />
|-<br />
| dcoutts<br />
| Duncan Coutts (Well-Typed LLP)<br />
| <br />
|<br />
|<br />
|<br />
|-<br />
| igloo<br />
| Ian Lynagh (Well-Typed LLP)<br />
| <br />
|<br />
|<br />
|<br />
|-<br />
| cies<br />
| Cies Breijs<br />
| +31646469087<br />
|<br />
|<br />
| Local (travelling from Rotterdam)<br />
|-<br />
| <br />
| Patrick Weemeeuw<br />
| +32495590214<br />
| Friday morning<br />
| Friday evening<br />
| Traveling from Leuven (BE)<br />
|-<br />
|<br />
| Jan Bessai<br />
| <br />
| Friday<br />
| Sunday<br />
|<br />
|-<br />
|<br />
| Edsko de Vries<br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| laar<br />
| Lars Corbijn<br />
| <br />
| <br />
| <br />
| Local (travelling from Hengelo)<br />
|-<br />
| <br />
| George Fourtounis<br />
| <br />
| <br />
| <br />
| Local<br />
|-<br />
|<br />
| Victor Denisov<br />
|<br />
|<br />
|<br />
| Not Yet decided<br />
|-<br />
|<br />
| Sjoerd Timmer<br />
| +31620086456<br />
|<br />
|<br />
| Local<br />
|-<br />
| nicmo<br />
| Augusto Passalaqua (UU)<br />
| +31644079781<br />
|<br />
|<br />
| Local<br />
|-<br />
| pcapriotti<br />
| Paolo Capriotti (Well-Typed LLP)<br />
| <br />
|<br />
|<br />
|<br />
|-<br />
| <br />
| Martijn van Steenbergen<br />
| <br />
|<br />
|<br />
| Local<br />
|-<br />
| Feuerbach<br />
| Roman Cheplyaka<br />
| +380662285780<br />
| Thursday evening<br />
| Sunday evening or Monday<br />
| Hostel Utrecht<br />
|-<br />
| arthurbaars<br />
| Arthur Baars (Universidad Politecnica de Valencia)<br />
| +34 646338710 <br />
| Thursday<br />
| Monday<br />
| Local<br />
|-<br />
| stefanooldeman<br />
| Stefano Oldeman<br />
| <br />
| Friday morning<br />
| Friday eve<br />
| Local<br />
|-<br />
|<br />
| Nikolaos Bezirgiannis (UU)<br />
| +31626845888<br />
|<br />
|<br />
| Local<br />
|-<br />
|<br />
| Tom Lokhorst (Q42)<br />
| <br />
|<br />
|<br />
| Local<br />
|-<br />
|<br />
| Ruben de Gooijer (UU)<br />
| +31 615462690<br />
| <br />
| <br />
| Local<br />
|-<br />
|<br />
| Bram Schuur (UU)<br />
| +31 644553557<br />
| <br />
| <br />
| Local<br />
|-<br />
|<br />
| Stanislav Chernichkin<br />
| +7 910 484 42 08<br />
| 19.04<br />
| 23.04<br />
| B&B Utrecht City Center<br />
|-<br />
| gdijkstra<br />
| Gabe Dijkstra (UU)<br />
| <br />
| <br />
| <br />
| Local<br />
|-<br />
| <br />
| Jeroen Bransen (UU)<br />
| <br />
|<br />
|<br />
| Local<br />
|-<br />
| <br />
| Atze Dijkstra (UU)<br />
| <br />
|<br />
|<br />
| Local<br />
|-<br />
-<br />
| doaitse<br />
| Doaitse Swierstra (UU)<br />
| +31 6 4613 6929<br />
|<br />
|<br />
| Local<br />
|-<br />
| <br />
| Wouter Swierstra (UU)<br />
| <br />
|<br />
|<br />
| Local<br />
|-<br />
| xnyhps<br />
| Thijs Alkemade (UU)<br />
|<br />
|<br />
|<br />
| Local<br />
|-<br />
| <br />
| Janis Voigtländer (Uni Bonn)<br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| joachifm<br />
| Joachim Fasting (University of Oslo)<br />
| +4790207081<br />
| Friday<br />
| Sunday morning<br />
| [http://www.bedandbreakfast-kilim.com/ Kilim Bed and Breakfast]<br />
|-<br />
| <br />
| João Alpuim (UU)<br />
| +31644309572<br />
|<br />
|<br />
| Local<br />
|-<br />
| basvandijk<br />
| Bas van Dijk (Erudify)<br />
| +41 791 285 624<br />
| Friday morning<br />
| Sunday evening<br />
|<br />
|-<br />
| roelvandijk<br />
| Roel van Dijk (RUN)<br />
| +31 6 12856453<br />
| Saturday morning<br />
| Sunday evening<br />
|</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Unicode-symbols&diff=38157Unicode-symbols2011-01-11T10:04:19Z<p>RoelVanDijk: Fixed some formatting</p>
<hr />
<div>[[Category:Packages]]<br />
<br />
== Overview ==<br />
<br />
An overview of the packages that provide Unicode symbols. <br />
<br />
Naming: A package '''<tt>X-unicode-symbols</tt>''' defines new symbols for functions and operators from the package '''<tt>X</tt>'''.<br />
<br />
All symbols are documented with their actual definition and information regarding their Unicode code point. They should be completely interchangeable with their definitions.<br />
<br />
Alternatives for existing operators have the same fixity. New operators will have a suitable fixity defined.<br />
<br />
==== UnicodeSyntax ====<br />
<br />
GHC offers the [http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#unicode-syntax UnicodeSyntax] language extension. If you decide to use Unicode in your Haskell source then this extension can greatly improve how it looks.<br />
<br />
== base-unicode-symbols ==<br />
<br />
Extra symbols for the [http://hackage.haskell.org/package/base base] package.<br />
<br />
API docs: http://hackage.haskell.org/package/base-unicode-symbols<br />
<br />
darcs get http://code.haskell.org/~roelvandijk/code/base-unicode-symbols<br />
<br />
==== Problematic symbols ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Original<br />
! Symbol<br />
! Code point<br />
! Name<br />
|-<br />
| not<br />
| &#xAC;<br />
| U+AC<br />
| NOT SIGN<br />
|}<br />
The problem with this symbol is that you would like to use it as an unary prefix operator:<br />
&not;(&not;x) &equiv; x<br />
Unfortunately this is not valid Haskell. The following is:<br />
(&not;)((&not;)x) &equiv; x<br />
But you can hardly call that an improvement over the simple:<br />
not (not x) &equiv; x<br />
<br />
==== New symbol ideas ====<br />
(''please add your own'')<br />
<br />
== containers-unicode-symbols ==<br />
<br />
Extra symbols for the [http://hackage.haskell.org/package/containers containers] package.<br />
<br />
API docs: http://hackage.haskell.org/package/containers-unicode-symbols<br />
<br />
darcs get http://code.haskell.org/~roelvandijk/code/containers-unicode-symbols<br />
<br />
==== New symbol ideas ==== <br />
(''please add your own'')<br />
<br />
== Input methods ==<br />
<br />
These symbols are all very nice but how do you type them?<br />
<br />
(''please add info for other editors'')<br />
<br />
=== Emacs ===<br />
<br />
'''Direct'''<br />
<br />
Enter symbols directly: <tt>[http://www.gnu.org/software/emacs/manual/html_node/emacs/International-Chars.html C-x 8 RET]</tt> (<tt>ucs-insert</tt>), then type either the character's name or its hexadecimal code point.<br />
<br />
'''Custom input method'''<br />
I wrote my own input method:<br />
<br />
darcs get http://code.haskell.org/~roelvandijk/code/haskell-unicode-input-method<br />
<br />
To automically load in haskell-mode put the following code in your .emacs file:<br />
(load "~/elisp/haskell-unicode-input-method/haskell-unicode-input-method")<br />
(add-hook 'haskell-mode-hook <br />
(lambda () (set-input-method "haskell-unicode")))<br />
Edit where appropriate depending on where you placed the elisp file.<br />
<br />
To manually enable use '''<tt>M-x set-input-method</tt>''' or '''<tt>C-x RET C-\</tt>''' with '''<tt>haskell-unicode</tt>'''. Note that the elisp file must be evaluated for this to work.<br />
<br />
Now you can simply type '''->''' and it is immediately replaced with '''&rarr;'''. Use '''<tt>C-\</tt>''' to toggle the input method. To see a table of all key sequences use '''<tt>M-x describe-input-method haskell-unicode</tt>'''. A sequence like <= is ambiguous and can mean either '''&lArr;''' or '''&le;'''. Typing it presents you with a choice. Type 1 or 2 to select an option or keep typing to use the default option.<br />
<br />
If you don't like the highlighting of partially matching tokens you can turn it off:<br />
<br />
(setq input-method-highlight-flag nil)<br />
<br />
'''Abbrev mode'''<br />
<br />
The [http://www.gnu.org/software/emacs/manual/html_node/emacs/Abbrevs.html Abbrev mode] is not suitable since it only deals with ''words'', not ''operators''.<br />
<br />
'''Agda'''<br />
<br />
Use Agda's [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Docs.UnicodeInput input method].<br />
<br />
=== System wide ===<br />
<br />
'''m17n input methods'''<br />
<br />
A set of input methods has been written by Urs Holzer for the [http://www.m17n.org m17n] library. The main goal of Urs is to build input methods for mathematical characters. However, most of the symbols used in the *-unicode-symbols packages can be written using Urs's methods. More information is available at [http://www.andonyar.com/rec/2008-03/mathinput/ Input Methods for Mathematics] page. For most Linux distributions, just download a [http://www.andonyar.com/rec/2008-03/mathinput/methods.tar.gz tarball], extract *.mim files to /usr/share/m17n and enable iBus for input methods.<br />
<br />
== Fonts ==<br />
<br />
The following free fonts have good Unicode coverage:<br />
<br />
* [http://www.gnome.org/fonts/ Bitstream Vera Font Family]<br />
* [http://dejavu-fonts.org/wiki/Main_Page DejaVu Font Family]<br />
* [http://linuxlibertine.sourceforge.net/ Linux Libertine Font]<br />
* [https://www.redhat.com/promo/fonts/ RedHat Liberation Fonts]</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Ghent_Functional_Programming_Group/BelHac/Register&diff=37195Ghent Functional Programming Group/BelHac/Register2010-10-08T18:48:14Z<p>RoelVanDijk: Added Roel van Dijk</p>
<hr />
<div>Important: Please wait for a confirmation email before booking any flights/hotels.<br />
<br />
Registration is via email to Jasper Van der Jeugt at<br />
<br />
jaspervdj+belhac@gmail.com<br />
<br />
with the subject<br />
<br />
BelHac registration <br />
<br />
and body containing the following information:<br />
<br />
Name:<br />
#haskell nick: (if applicable)<br />
Email:<br />
Food restrictions:<br />
Days attending: <br />
<br />
Here is an example:<br />
<br />
Name: Jasper Van der Jeugt<br />
Nick: jaspervdj<br />
Email: jaspervdj@gmail.com<br />
Food restrictions: Raw flesh only<br />
Days attending: Friday, saturday and sunday<br />
<br />
If you want, you can also add you name here:<br />
<br />
{| class="wikitable"<br />
! Nickname<br />
! Real Name<br />
! Affiliation<br />
! Mobile #<br />
! Email<br />
! Arriving - Departing<br />
! Accomodation<br />
|-<br />
| jaspervdj<br />
| Jasper Van der Jeugt<br />
| Ghent University<br />
| +32 476 26 48 47<br />
| jaspervdj@gmail.com<br />
| <br />
| Has a small place in Ghent<br />
|-<br />
| Itkovian<br />
| Andy Georges<br />
| Ghent University/FWO<br />
| <br />
| itkovian@gmail.com<br />
|<br />
| Lives in Ostend, arrives by train on daily basis<br />
|-<br />
| Javache<br />
| Pieter De Baets<br />
| Ghent University<br />
| <br />
| pieter.debaets@gmail.com<br />
|<br />
|<br />
|-<br />
| boegel<br />
| Kenneth Hoste<br />
| Ghent University<br />
| <br />
| kenneth.hoste@ugent.be<br />
|<br />
| commute to/from Ghent daily<br />
|-<br />
| BCoppens<br />
| Bart Coppens<br />
| Ghent University<br />
| <br />
| bart.coppens@elis.ugent.be<br />
|<br />
|<br />
|-<br />
| jejansse<br />
| Jeroen Janssen<br />
| VUB<br />
|<br />
| jejansse@gmail.com<br />
|<br />
| Lives in Ghent.<br />
|-<br />
| Feuerbach<br />
| Roman Cheplyaka<br />
| <br />
| +380662285780<br />
| roma@ro-che.info<br />
| unknown yet<br />
| unknown yet<br />
|-<br />
| solidsnack<br />
| Jason Dusek<br />
| Heroku<br />
| +1 415 894 2162<br />
| jason.dusek@gmail.com<br />
| 5th-7th<br />
| Probably Monasterium.<br />
|-<br />
| kosmikus<br />
| Andres L&ouml;h<br />
| Well-Typed LLP<br />
|<br />
| mail@andres-loeh.de<br />
| 5th-7th<br />
|<br />
|-<br />
| Igloo<br />
| Ian Lynagh<br />
| Well-Typed LLP<br />
|<br />
| igloo@earth.li<br />
| 5th-7th<br />
|<br />
|-<br />
| dcoutts<br />
| Duncan Coutts<br />
| Well-Typed LLP<br />
|<br />
| duncan.coutts@googlemail.com<br />
| 5th-7th<br />
|<br />
|-<br />
| ADEpt<br />
| Dmitry Astapov<br />
| Well-Typed LLP<br />
|<br />
| dastapov@gmail.com<br />
| 5th-7th<br />
|<br />
|-<br />
| wvdschel<br />
| Wim Vander Schelden<br />
| Ghent University<br />
| <br />
| belhac@fixnum.org<br />
| <br />
| Lives in Ghent<br />
|-<br />
| sjoerd_visscher<br />
| Sjoerd Visscher<br />
| SDL Xopus<br />
| <br />
| sjoerd@w3future.com<br />
| 5th-7th<br />
| youth hostel<br />
|-<br />
| mietek<br />
| Miëtek Bak<br />
| Erlang Solutions<br />
| <br />
| mietek@gmail.com<br />
| 5th-7th<br />
| Open for suggestions<br />
|<br />
|-<br />
| <br />
| Steven Keuchel<br />
| Utrecht University<br />
| <br />
| <br />
| 5th-7th<br />
| <br />
|-<br />
| chr1s<br />
| Chris Eidhof<br />
| <br />
| <br />
| chris@eidhof.nl<br />
| 5th-7th<br />
| youth hostel<br />
|-<br />
|fphh<br />
|Heinrich Hördegen<br />
|Funktionale Programmierung<br />
|<br />
|hoerdegen@laposte.net<br />
|5th-7th<br />
|Open for suggestions<br />
|-<br />
| <br />
| Tom Lokhorst<br />
| <br />
| <br />
| tom@lokhorst.eu<br />
| 5th-7th<br />
| youth hostel<br />
|-<br />
| sioraiocht<br />
| Tom Harper<br />
| Oxford University Computing Laboratory<br />
| +44 7533 998 591<br />
| rtomharper@gmail.com<br />
| Friday-Sunday<br />
| <br />
|-<br />
| mcclurmc<br />
| Mike McClurg<br />
| <br />
| <br />
| mike.mcclurg@gmail.com<br />
| Friday-Sunday<br />
| <br />
|-<br />
| chrisdone<br />
| Chris Done<br />
| CREATE-NET<br />
| TBA<br />
| chrisdone@gmail.com<br />
| 5th-7th<br />
| <br />
|-<br />
| lpeterse<br />
| Lars Petersen<br />
| University of Osnabrück<br />
| <br />
| info@lars-petersen.net<br />
| 5th-7th<br />
| Hostel<br />
|-<br />
| sfvisser<br />
| Sebastiaan Visser<br />
| Silk<br />
| <br />
| haskell@fvisser.nl<br />
| 5th-7th<br />
| youth hostel<br />
|-<br />
| alatter<br />
| Antoine Latter<br />
|<br />
|<br />
| aslatter@gmail.com<br />
| 5th - 7th<br />
| Hostel<br />
|-<br />
| marcmo<br />
| oliver mueller<br />
|<br />
|<br />
| oliver.mueller@gmail.com<br />
| 5th - 7th<br />
| Hostel<br />
|-<br />
| kayuri<br />
| Yuriy Kashnikov<br />
| <br />
| <br />
| yuriy.kashnikov@gmail.com<br />
| 5th-7th<br />
| <br />
|-<br />
| nomeata<br />
| Joachim Breitner<br />
| <br />
| <br />
| mail@joachim-breitner.de<br />
| 5th-7th<br />
| still looking<br />
|-<br />
| dons<br />
| Don Stewart<br />
| [http://www.galois.com Galois, Inc]<br />
| 07961033604<br />
| dons@galois.com<br />
| 5th - 7th.<br />
| <br />
|-<br />
| basvandijk<br />
| Bas van Dijk<br />
| <br />
| +31 614065248<br />
| v.dijk.bas@gmail.com<br />
| 5th - 7th<br />
| still looking<br />
|-<br />
| roelvandijk<br />
| Roel van Dijk<br />
| <br />
| +31 612856453<br />
| vandijk.roel@gmail.com<br />
| 5th - 7th<br />
| still looking<br />
|}</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Hackage_wiki_page_per_project_discussion&diff=32687Hackage wiki page per project discussion2009-12-21T09:02:02Z<p>RoelVanDijk: </p>
<hr />
<div>== Purpose of this page ? ==<br />
collect thoughts about whether we should provide a wiki page (and maybe even more advanced features such as bug trackers) for all projects hosted on hackage<br />
<br />
I'll post a link to this page to haskell-cafe so everyone should participate<br />
<br />
== Why a Wiki ==<br />
We do have about 1500 packages on hackage. Hackage was made life easier.<br />
While packaging some packages for nix (using [[Hack-Nix]]) I had to write some patches.<br />
<br />
If you have a patch what to do?<br />
Duncan Coutts proposed contacting the maintainer. If you don't receive replies within a time frame write to the haskell-cafe mailinglist. If you can't find him become the new maintainer.<br />
<br />
While contacting the maintainer works very well within 3 days in most cases there are situations where maintainers can't reply because they are on holiday or got very busy.. In these cases I'd like to put my patch somewhere so that others can find them.<br />
<br />
== What could a wiki page be used for? ==<br />
<br />
<br />
a) patches (which are removed when maintainers integrate them upstream)<br />
<br />
b) Howtos and pitfalls (written by users or maintainers)<br />
<br />
c) references to similar projects pointing out differences.<br />
<br />
d) a smart lazy changelog. If a user hits a change he can add this to the<br />
wiki so that others can find out faster which version constraints to<br />
add to their .cabal file.<br />
<br />
This looks like this:<br />
2.20: renamed foo to bar.<br />
<br />
2.48: type change of iwillneverChange :: Int to Maybe Int<br />
<br />
e) a list of changes which will go into the next release of a package.<br />
This may help you figuring out whether you should download the darcs repository.<br />
<br />
f) many other ideas I can't think about yet.<br />
<br />
...<br />
<br />
<br />
== implementation details: ==<br />
<br />
design could look like this:<br />
http://mawercer.de/~marc/hackage-link-example.jpg<br />
<br />
The link would point to the haskell wiki having the url suffix /project-name.<br />
<br />
== When a wiki page can replace a .cabal file update ==<br />
<br />
* naturally it takes some time until most recent cabal updates are used by mainstream.. Eg there is a way to add repository locations now.. But have a look at [http://hackage.haskell.org/packages/archive/happy/1.18.4/happy.cabal happy.cabal] and smile :) Btw: I adopted this usage of the source-repository field for one project.<br />
<br />
* minor dependency changes<br />
<br />
* tell users about experimental branches<br />
<br />
* it's easier to provide important information such as:<br />
<br />
"This package is superseded by XY because: ..."<br />
<br />
** We already have a mechanism to deprecate packages or to mark them as superseded. --[[User:DuncanCoutts|DuncanCoutts]] 00:25, 12 December 2009 (UTC)<br />
<br />
[[User:MarcWeber|Marc Weber]]: Can you explain how this works or point me to the documentation?<br />
<br />
The main point about this wiki idea is that you can attach arbitrary information and you don't have to wait for anyone to do so.<br />
Get things done. Provide patches. Link them on the wiki.<br />
Come back later and discuss your proposals with the maintainer.<br />
Keep summaries of discussions on subjects accessible by everyone.<br />
...<br />
<br />
Of course I know that the maintainers are the people doing the real work.<br />
But look at it from a different view: Having such a forum for all projects by default also means that a maintainer can let others do some of the work knowing that they don't have to reply within some days.<br />
<br />
The wiki can host all information which may be useful but which wasn't foreseen by hackage or cabal devs. We must keep agile and move forward only.<br />
<br />
== Concerns ==<br />
<br />
My (DuncanCoutts) concern is about the consent from package authors. Hackage is a social bargain. We ask package authors to distribute their work through hackage because it provides benefits to the community. If we impose too much on package authors then they may decide it's just not worth it.<br />
<br />
In particular, if we automatically create a wiki page for every package then we are imposing additional obligations on package authors. As a package author I might be concerned that this wiki page duplicates an existing home page or bug tracking system. If there's a wiki page about my project then I am effectively obligated to check it from time to time, since users will inevitably report bugs etc there. It is that extra obligation that package authors may resent.<br />
<br />
There is no problem with such a feature being opt-in, but whether it is something we require and impose on package authors needs much more of a social consensus before we go ahead.<br />
<br />
Reply [[User:MarcWeber|Marc Weber]]: Everybody knows that it is wiki content and will take care.<br />
<br />
About effort: Note that package authors can watch their wiki pages easily.<br />
Authors and maintainers already do the hard work. Watching a wiki page is not mach work compared to writing a library. But they may find wiki contents of foreign projects that useful that they provide some contents their selves<br />
<br />
The above concerns amount to saying that there is (or may be) no value added for the user but nevertheless makes extra work for the maintainer. My (Daniel Wagner) concern is that there may actually be value ''removed'' for the user. A bad, incomplete, or non-existent wiki page can be worse than no page at all, because new users may view the wiki page as the canonical resource. This is especially so because many of the smaller projects have minimal or non-existent homepages (often just the root of a darcs repository) and minimal or non-existent documentation; this puts users in the habit of searching elsewhere for information about using the package. Maintainers that do end up putting effort into their project's pages and documentation will suffer as a result, especially if the projects are too small to garner many wiki-editing users. In this case, an unhelpful wiki page may scare away potential users, despite the existence of other useful resources.<br />
<br />
== concern "The wiki will be outdated" ==<br />
True. Every user must know that wikis naturally are out of date :)<br />
But the question is: Can one wiki page (containing an example)<br />
generate more value than some outdated pages cause damage to you?<br />
<br />
It's hard to say because haskellwiki wiki pages can be found when searching from the start page as well.<br />
<br />
Maybe we can ask users to add the package version so that users will see themselves that content is outdated?<br />
<br />
<br />
Don't think about other people. Think about yourself: Do you mind reading some outdated wiki pages? Do you appreciate the valuable contents which will be exist as well? If you don't mind reading some outdated pages and if you'd like to see more examples about how to use packages you basically support this idea!<br />
Let's not forget that haskell.org is a wiki itself. And naturally parts are outdated as well. You still don't want to miss it, do you?<br />
<br />
== wiki alternatives ==<br />
If content isn't put on a wiki what do people do instead?<br />
* They may do nothing (bad)<br />
* They may write a blog (bad because others don't find it or because content gets out of date). Which way is more likely providing you with valuable information: A blog found by google or an attached wiki page people can keep up to date?<br />
* They may write to the mailinglist. Things are archived forever. On the wiki they are as well but not only a small amount of visitors ever looks at the history of a page..<br />
<br />
== my project already has a wiki ..==<br />
Fine. In this case the haskellwiki wiki page will only have one link telling the user about your page.<br />
<br />
== progress and feedback ==<br />
I've send a short mail to about 100 maintainers to get to know what they think about this idea.<br />
<br />
Consider adding your name only for spam reasons (but send your emal address to marco-oweber@gmx.de so that I can associate them with packages on hackage to got to know who didn't reply)<br />
<br />
I support this idea:<br />
* marco-oweber@gmx.de (Marc Weber)<br />
* clawsie@fastmail.fm (Brad Clawsie)<br />
* newanon@yandex.ru (Oleg Ivanov)<br />
<br />
I support but want opt-out:<br />
* f.nfgnava@tznvy.pbz/rot13 (Sergey Astanin) I think default project wiki is a good thing for users, especially given that many projects don't have links neither to the web page nor to the bug tracker, some are unmaintained public domain, and some don't have even e-mail of the maintainer. However, I think that this wiki policy should be applied only to such “orphaned” projects without evident maintainer/infrastructure. When there is a valid link to project page, bug tracker or stand alone wiki, it's better to direct users there.<br />
<br />
I support but I want opt-in:<br />
* daniel@wagner-home.com (Daniel Wagner) I believe opt-in is the Right Thing, so would vote here even if I didn't have the misgivings I mention above<br />
* daniel.schoepe@googlemail.com (Daniel Schoepe) In general I think it's a very good idea, but imposing it on every package author might discourage some, especially people new to Hackage.<br />
* the idea makes me nervous, but I can live with opt-in (Eric Kow)<br />
* vandijk.roel@gmail.com (Roel van Dijk) I wouldn't mind it as long as it is completely optional. But it is already supported just by setting your homepage to a haskell.org wiki page. And you can always ask a maintainer if he/she can create a wiki for a project or if it's ok if you create a wiki for their project.<br />
<br />
I don't like the idea even if there was a warning such as "This content is contributed by maintainers and users and may be out of date.":<br />
<br />
If you vote here, make sure you've read "wiki alternatives". You can clean up the wiki page. You can't clean up foreign blogs.<br />
* EvanMartin (exactly what Duncan wrote -- I don't have time to vet a third-party page and keep it up to date; I have seen obsolete wikis for too many projects in my time. If I want to use a wiki I could just set it as the home page for my project. Consider adding a "wiki" link to the package description format.)<br />
<br />
I don't care:<br />
*<br />
<br />
I won't tell you:<br />
*<br />
<br />
== users view (beginners) ==<br />
Daniel Wagner told me that the thinks beginners will suffor most.<br />
So I'll start a thread on beginners@haskell.org and ask them :-)<br />
<br />
I'm a beginner, I don't mind reading outdated content. When I see a code snippet I'm going to copy paste it int ghci. If it doesn't work may be challenged and may fix it. Of course I'll contribute by solution and put it on the wiki. I think that such a scratch pad is a nice idea in general.<br />
* put your name here<br />
<br />
I'm a beginner and I fear reading about outdated content. This means that you fear the damage reading outdated content is bigger than the gains you have by reading up to date contents.<br />
* put your name here<br />
<br />
== mailinglist threads ==<br />
* [http://news.gmane.org/gmane.comp.lang.haskell.cafe haskell-cafe]<br />
<br />
* [http://thread.gmane.org/gmane.comp.lang.haskell.beginners/2942 beginners@haskell.org]<br />
<br />
<br />
== Notes ==<br />
You can watch this page</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Haskell_mode_for_Emacs&diff=30602Haskell mode for Emacs2009-10-05T07:49:54Z<p>RoelVanDijk: Fixed hayoo URL in elisp snippet</p>
<hr />
<div>haskell-mode is a major mode for Emacs and XEmacs specifically for writing Haskell code. You can get HaskellMode from the web page: http://www.haskell.org/haskell-mode/ or on Debian you can type <code>apt-get install haskell-mode</code> (although this currently doesn't have the latest version). <br />
<br />
==Obtaining the CVS version==<br />
<br />
<code>cvs -d :pserver:anoncvs@cvs.haskell.org:/cvs login # password 'cvs' </code><br />
<br />
<code>cvs -d :pserver:anoncvs@cvs.haskell.org:/cvs co fptools/CONTRIB/haskell-modes/emacs</code><br />
<br />
==Minimal setup==<br />
<br />
Insert in your ~/.emacs or other appropriate file:<br />
<br />
<code>(load "/path/to/haskell-mode/haskell-site-file")</code><br />
<br />
==Tips and use==<br />
Handy keybindings in haskell-mode. See the documentation <code>C-h m</code> for more information:<br />
*<code>C-c C-=</code> inserts an = sign and lines up type signatures and other pattern matches nicely.<br />
*<code>C-c C-|</code> inserts a guard<br />
*<code>C-c C-o</code> inserts a guard <hask>| otherwise =</hask> and lines up existing guards<br />
*<code>C-c C-w</code> inserts a where keyword<br />
*<code>C-c C-.</code> aligns code over a region in a "sensible" fashion.<br />
<br />
Now in version 2.2:<br />
*<code>C-c C-t</code> gets :type for symbol at point, and remembers it<br />
*<code>C-u C-c C-t</code> inserts a type annotation, for symbol at point, on the line above<br />
*<code>C-c C-i</code> gets :info for symbol at point<br />
*<code>C-c M-.</code> find definition of (interpreted) symbol at point<br />
<br />
(See the section below on [[#inf-haskell.el:_the_best_thing_since_the_breadknife|inf-haskell]].)<br />
<br />
Here's an example for <code>C-c C-=</code>. Put your cursor after myInt and hit <code>C-c C-=</code><br />
<haskell><br />
blah :: Int -> Int<br />
blah myInt<br />
</haskell><br />
note how the function signature is reindented to match the column of the = sign.<br />
<haskell><br />
blah :: Int -> Int<br />
blah myInt =<br />
</haskell><br />
<br />
You could also achieve the same effect by selecting the region and typing <code>C-c C-.</code><br />
<br />
You can also use Haskell-Mode to load Emacs buffers with Haskell code in either Hugs or GHC. To load something in Hugs or ghci, type <code>C-c C-l</code> to load the file. Then, you can go on to type <code>C-c C-r</code> (or simply <code>C-c C-l</code> again) to reload the current module when you have made a change.<br />
<br />
=== Indentation ===<br />
Indentation is one thing that nearly all programming modes provide. However, indenting Haskell code is very hard: for a given line, there are nearly always more than column for which indentation makes sense. For example, imagine the following is open in a haskell-mode buffer, where <code>!</code> represents the point:<br />
<br />
<haskell><br />
foo :: Int -> String<br />
foo 0 = f 4 ++ s<br />
where f 4 = "hello" ++ <br />
!<br />
</haskell><br />
<br />
If you ask haskell-mode to indent for you, where should it indent to? There are four basic options:<br />
<br />
<ol><br />
<li><br />
You want to finish off the expression you were writing in the last line. Haskell-mode indents to be underneath the <code>"</code> character at the beginning of <code>"hello"</code>:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
This is debatably a bad choice as you'd probably want to indent a bit further in to make it clear that you were carrying on an expression, but the layout rule would accept something like the following:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
"world"<br />
</haskell><br />
<br />
</li><br />
<li><br />
You want to add a second equation for <code>f</code>. Haskell-mode will indent to line up with the first argument, and fill in the <code>f</code> in the equation:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
f !<br />
</haskell><br />
<br />
This is an unlikely choice as the expression in the previous line isn't complete, but haskell-mode isn't smart enough to know that. (If <code>f</code> had been something without arguments, like <hask>where f = "hello"</hask>, then it's impossible to have more than one equation and haskell-mode won't offer this indentation level.)<br />
</li><br />
<li><br />
You want to add a second binding to the <code>where</code>-block. Haskell-mode indents to line up with the <code>f</code>:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
</li><br />
<li>You want to start an entirely new top-level binding. Haskell-mode indents to the first column:<br />
<br />
<haskell><br />
foo :: Int -> String<br />
foo 0 = f 4 ++ s<br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
</li><br />
</ol><br />
<br />
These four locations can be reached by repeatedly pressing <code>TAB</code>. This is what's known as the tab-cycle. The innermost location is offered first, then cycling progresses outwards. Although this may seem like an inefficient system (and it is indeed a shame that Haskell's design didn't result in an unambiguous indentation system), you do quickly get used to the tab-cycle and indenting Haskell code.<br />
<br />
==== indent-region ====<br />
Using indent-region is generally a bad idea on Haskell code, because it would need to know which of the tab-cycle stops you wish to choose for each line. The innermost one is chosen in each case, which often results in unusable code. Moral: just don't use indent-region with haskell-mode.<br />
<br />
==== Unicodifying symbols (Pretty Lambda for Haskell-mode) ====<br />
In Haskell code, you can end up using a lot of mathematical symbols. It is possible to hack the fontifying features of Emacs to change the ASCII textual representations of arrows and operators into the nice-looking real symbols, much like you could with TeX. The following code is a compilation of Emacs lisp code found on the Emacs wiki on the [http://www.emacswiki.org/cgi-bin/wiki/PrettyLambda#toc4 Pretty Lambda] page (that page also has examples of how to apply the general Unicode defuns to other languages):<br />
<br />
HOWEVER: due to the symbols taking up less space, this has the unfortunate side effect of changing the indentation stops that the indent key offers. This will mean that your code may not look properly aligned to those who do not have this feature in their editor, or could even mean that your code means something different to how it looks. (It is possible to contrive an example that looks correct in emacs, but actually fails to compile). The following is left for interest, but probably should NOT be used.<br />
<br />
Haskell-mode has included this feature for a long time now, so you probably just need to <code>(setq haskell-font-lock-symbols t)</code> in your .emacs to use this feature.<br />
<br />
<code><br />
(defun unicode-symbol (name)<br />
"Translate a symbolic name for a Unicode character -- e.g., LEFT-ARROW <br />
or GREATER-THAN into an actual Unicode character code. "<br />
(decode-char 'ucs (case name <br />
('left-arrow 8592)<br />
('up-arrow 8593)<br />
('right-arrow 8594)<br />
('down-arrow 8595) <br />
('double-vertical-bar #X2551) <br />
('equal #X003d)<br />
('not-equal #X2260)<br />
('identical #X2261)<br />
('not-identical #X2262)<br />
('less-than #X003c)<br />
('greater-than #X003e)<br />
('less-than-or-equal-to #X2264)<br />
('greater-than-or-equal-to #X2265) <br />
('logical-and #X2227)<br />
('logical-or #X2228)<br />
('logical-neg #X00AC) <br />
('nil #X2205)<br />
('horizontal-ellipsis #X2026)<br />
('double-exclamation #X203C)<br />
('prime #X2032)<br />
('double-prime #X2033)<br />
('for-all #X2200)<br />
('there-exists #X2203)<br />
('element-of #X2208) <br />
('square-root #X221A)<br />
('squared #X00B2)<br />
('cubed #X00B3) <br />
('lambda #X03BB)<br />
('alpha #X03B1)<br />
('beta #X03B2)<br />
('gamma #X03B3)<br />
('delta #X03B4))))<br />
<br />
(defun substitute-pattern-with-unicode (pattern symbol)<br />
"Add a font lock hook to replace the matched part of PATTERN with the <br />
Unicode symbol SYMBOL looked up with UNICODE-SYMBOL."<br />
(interactive)<br />
(font-lock-add-keywords<br />
nil `((,pattern <br />
(0 (progn (compose-region (match-beginning 1) (match-end 1)<br />
,(unicode-symbol symbol)<br />
'decompose-region)<br />
nil))))))<br />
<br />
(defun substitute-patterns-with-unicode (patterns)<br />
"Call SUBSTITUTE-PATTERN-WITH-UNICODE repeatedly."<br />
(mapcar #'(lambda (x)<br />
(substitute-pattern-with-unicode (car x)<br />
(cdr x)))<br />
patterns))<br />
<br />
(defun haskell-unicode ()<br />
(interactive)<br />
(substitute-patterns-with-unicode<br />
(list (cons "\\(<-\\)" 'left-arrow)<br />
(cons "\\(->\\)" 'right-arrow)<br />
(cons "\\(==\\)" 'identical)<br />
(cons "\\(/=\\)" 'not-identical)<br />
(cons "\\(()\\)" 'nil)<br />
(cons "\\<\\(sqrt\\)\\>" 'square-root)<br />
(cons "\\(&&\\)" 'logical-and)<br />
(cons "\\(||\\)" 'logical-or)<br />
(cons "\\<\\(not\\)\\>" 'logical-neg)<br />
(cons "\\(>\\)\\[^=\\]" 'greater-than)<br />
(cons "\\(<\\)\\[^=\\]" 'less-than)<br />
(cons "\\(>=\\)" 'greater-than-or-equal-to)<br />
(cons "\\(<=\\)" 'less-than-or-equal-to)<br />
(cons "\\<\\(alpha\\)\\>" 'alpha)<br />
(cons "\\<\\(beta\\)\\>" 'beta)<br />
(cons "\\<\\(gamma\\)\\>" 'gamma)<br />
(cons "\\<\\(delta\\)\\>" 'delta)<br />
(cons "\\(<nowiki>''</nowiki>\\)" 'double-prime)<br />
(cons "\\('\\)" 'prime)<br />
(cons "\\(!!\\)" 'double-exclamation)<br />
(cons "\\(\\.\\.\\)" 'horizontal-ellipsis))))<br />
<br />
(add-hook 'haskell-mode-hook 'haskell-unicode)</code><br />
<br />
== Bugs ==<br />
Bugs and feature requests should be sent to the maintainer [mailto:monnier@iro.umontreal.ca Stefan Monnier].<br />
For people using the Debian package, Debian maintains a [http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=haskell-mode list of bugs] for haskell-mode, they should be reported there.<br />
<br />
===XEmacs===<br />
On some the GNU/Linux systems with XEmacs, admittedly, only verified on Ubuntu and Debian and with haskell-mode 2.2, there is a system function missing that interferes with automatic indenting. Secondly, there seems to be an issue with setting the <code-lisp>haskell-default-face</code-lisp> to <code-lisp>nil</code-lisp>.<br />
<br />
====line-end-position====<br />
<br />
To fix this, find where the haskell mode package is installed on your system. (Usually <code>/usr/share/emacs/site-lisp/haskell-mode</code>). Edit the file <code>haskell-indent.el</code> and add the lines:<br />
<pre-lisp><br />
(eval-and-compile<br />
<br />
;; If `line-end-position' isn't available provide one.<br />
(unless (fboundp 'line-end-position)<br />
(defun line-end-position (&optional n)<br />
"Return the `point' of the end of the current line."<br />
(save-excursion<br />
(end-of-line n)<br />
(point)))))<br />
</pre-lisp><br />
right after the comments at the top. That should fix the issue.<br />
<br />
====haskell-default-face====<br />
<br />
This one shows up when typing in code (at various spots - most often when typing a qualified function, such as <hask>List.map</hask>.)<br />
<br />
To fix this one, edit the file <code>haskell-font-lock.el</code>. Look for the line that says:<br />
<pre-lisp><br />
(defvar haskell-default-face nil)<br />
</pre-lisp><br />
and change this to <br />
<pre-lisp><br />
(defvar haskell-default-face 'default)<br />
</pre-lisp><br />
In my version, this is line 168.<br />
<br />
Then, look for the line that says:<br />
<pre-lisp><br />
(,qvarid 0 haskell-default-face)<br />
</pre-lisp><br />
and change it to<br />
<pre-lisp><br />
(,qvarid 0 (symbol-value 'haskell-default-face))<br />
</pre-lisp><br />
<br />
For me, this is line 326 of the file.<br />
YMMV - hope this helps.<br />
<br />
<!--<br />
=== GNU Emacs ===<br />
<br />
==== ghci buffer infested with "^J"s, C-c C-t doesn't work ====<br />
<br />
(only happens after loading a haskell file into ghci)<br />
<br />
--><br />
<br />
<br />
== inf-haskell.el: the best thing since the breadknife ==<br />
inf-haskell.el is _awesome_. At one point I decided to sit down and write a list of functions I'd love to have in haskell-mode, intending to write them myself. I thought I'd check to see whether the key shortcuts I'd chosen were free but I was surprised to find that ''every one'' of these functions is already provided by inf-haskell.el! Here's a selection of the highlights:<br />
<br />
<br />
=== Getting set up ===<br />
inf-haskell.el is usually already setup as part of the haskell-mode package, so there is nothing special to do for it. On some systems, you may need this in your .emacs:<br />
<br />
<pre-lisp><br />
(require 'inf-haskell)<br />
</pre-lisp><br />
<br />
To use the following functions, first find a .hs file, then hit C-c C-l (inferior-haskell-load-file). This fires up Hugs or Ghci (you can change this by customising haskell-program-name) on your file. Don't worry if it's not an isolated module, GHCi will load all the modules it imports as normal. You can even load entire programs this way by using C-c C-l on the Main.hs file. If everything loads without errors, you'll be able to use the functions below.<br />
<br />
=== inferior-haskell-type (C-c C-t) ===<br />
Say you have the following code:<br />
<br />
foo = foldr (+) 0 [1..20]<br />
<br />
Perhaps you've forgotten the order of arguments to foldr. It's easily done; I can never remember whether the operation or final value comes first. That's easy to check: just put your point between the 'f' and 'r' of 'foldr' and hit C-c C-t RET. The type of foldr will be revealed in the echo area. This isn't particularly impressive; haskell-doc.el already did this. However, this will work for ''any'' function in the module in question ''or'' in those modules imported by the current module (including the standard libs)!<br />
<br />
If you find that the type shown in the echo area is overwritten after a short amount of time (or any other such problem, of course), please report it as a bug. We know of no such bug, but someone apparently bumped into some such problem which he says he worked around by disabling doc-mode and decl-scan:<br />
<br />
To turn off haskell-doc-mode, add the following to your .emacs:<br />
<pre-lisp><br />
(remove-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)<br />
</pre-lisp><br />
To turn off haskell-decl-scan, just refrain from turning it on (it's not enabled by default).<br />
<br />
(P.S. I re-use haskell-doc-mode to save queried type info, and re-display it in the minibuffer. Disabling doc mode would disable that. -- mrd)<br />
<br />
Another nice feature of this function is the ability to automatically insert type signatures for the function at point on the line above. For example, suppose you have the below open in Emacs, with the point represented by -!-:<br />
<br />
-!-map _ [] = []<br />
map f (x:xs) = f x : map f xs<br />
<br />
And press C-u C-c C-t (note the prefix argument), it will result in the following:<br />
<br />
map :: (a -> b) -> [a] -> [b]<br />
-!-map _ [] = []<br />
map f (x:xs) = f x : map f xs<br />
<br />
=== inferior-haskell-info (C-c C-i) ===<br />
The :info command in GHCi/Hugs is extremely useful; it'll tell you:<br />
<br />
* The definition of an algebraic datatype given its name. E.g. try <code>:info Bool</code>. The output will contain something like <code>data Bool = True | False</code>.<br />
* The classes a type instantiates given the type's name. <code>:info Bool</code> will also give you the classes Bool instantiates. If you can't see an instance you think should be there, make sure the module where that instance is declared is loaded.<br />
* The type of a function, given its name.<br />
* The types of the methods of a class, and the number of arguments of that class, given the class name.<br />
* The expansion of a type synonym given that synonym's name.<br />
<br />
And for all of the above, :info will also tell you the filename and line where that thing is defined. inferior-haskell-info lets you hook into this power. Use it with C-c C-i on anything within a Haskell file.<br />
<br />
=== inferior-haskell-find-definition (C-c M-.) ===<br />
This one needs little explanation. Sometimes you just need to find the source of a function, or datatype, or class, or type synonym etc. to see how it works, and this function lets you do just that. Unfortunately, it won't work on the standard lib modules or anything that isn't 'local' to your project. This is one of the most useful functions inf-haskell.el provides.<br />
<br />
(Basically, it only works on interpreted code, for which ghci has location information. If you want a more general find-definition, use hasktags to create a TAGS file and then use the normal emacs <code>M-.</code> with that. -- mrd)<br />
: Note that you can also create a TAGS file using GHCi's :etags command. [[User:DavidHouse|DavidHouse]] 14:38, 29 April 2007 (UTC)<br />
<br />
: Again, :etags/:ctags only works for interpreted code.<br />
<br />
== Tricks and tweaks ==<br />
<br />
=== Automatic unit testing ===<br />
Here's a cute trick I've evolved:<br />
<br />
I'm a great fan of [[unit test first]], as described by eXtremeProgramming on TheOriginalWiki.<br />
<br />
With the code below, I can press F12 and immediately run all of my unit tests, and immediately see whether they all passed or not.<br />
I've put all of my unit tests into their own file with a main function that runs the tests and gives an exitcode according to the test results. I've specified that the compile-command for that file compiles and runs the file.<br />
<br />
This elisp code will run the <code>compile</code> command from the F12 key in emacs. The output will popup a new window twelve lines tall. If the compilation is successful (exitcode zero) the window goes away. If the exitcode is 1 or greater, the window stays so you can see the output.<br />
<pre-lisp><br />
(require 'compile)<br />
<br />
;; this means hitting the compile button always saves the buffer<br />
;; having to separately hit C-x C-s is a waste of time<br />
(setq mode-compile-always-save-buffer-p t)<br />
;; make the compile window stick at 12 lines tall<br />
(setq compilation-window-height 12)<br />
<br />
;; from enberg on #emacs<br />
;; if the compilation has a zero exit code, <br />
;; the windows disappears after two seconds<br />
;; otherwise it stays<br />
(setq compilation-finish-function<br />
(lambda (buf str)<br />
(unless (string-match "exited abnormally" str)<br />
;;no errors, make the compilation window go away in a few seconds<br />
(run-at-time<br />
"2 sec" nil 'delete-windows-on<br />
(get-buffer-create "*compilation*"))<br />
(message "No Compilation Errors!"))))<br />
<br />
<br />
;; one-button testing, tada!<br />
(global-set-key [f12] 'compile)<br />
</pre-lisp><br />
<br />
<br />
This Haskell code has some Emacs local variable settings at the bottom specifying what the compile-command should be for this buffer.<br />
<haskell><br />
import HUnit<br />
import System<br />
<br />
myTestList = <br />
TestList [<br />
"add numbers" ~: 5 ~=? (3 + 2)<br />
,"add numbers" ~: 5 ~=? (3 + 3)<br />
]<br />
<br />
h = runTestTT myTestList<br />
<br />
main = do c <- h<br />
putStr $ show c<br />
let errs = errors c<br />
fails = failures c<br />
System.exitWith (codeGet errs fails)<br />
<br />
codeGet errs fails<br />
| fails > 0 = ExitFailure 2<br />
| errs > 0 = ExitFailure 1<br />
| otherwise = ExitSuccess<br />
<br />
-- Local Variables:<br />
-- compile-command: "ghc --make -o Test_Demo -i/home/shae/src/haskell/libraries/ HUnitDemo.hs && ./Test_Demo"<br />
-- End:<br />
</haskell><br />
<br />
<br />
If you have any questions, ideas, or suggestions for this code, the maintainer would love to hear them.<br />
<br />
=== Hoogle integration ===<br />
From haskell-mode version 2.4 onwards, the built-in function haskell-hoogle will hoogle the identifier at point.<br />
<br />
=== Using rectangular region commands ===<br />
<br />
Emacs has a set of commands which operate on the region as if it were rectangular. This turns out to be extremely useful when dealing with whitespace sensitive languages.<br />
<br />
<code>C-x r o</code> is "Open Rectangle". It will shift any text within the rectangle to the right side. Also see:<br />
<br />
<code>C-x r t</code> is "String Rectangle". It will shift any text within the rectangle over to the right, and insert a given string prefixing all the lines in the region. If comment-region didn't already exist, you could use this instead, for example.<br />
<br />
<code>C-x r d</code> is "Delete Rectangle". It will delete the contents of the rectangle and move anything on the right over.<br />
<br />
<code>C-x r r</code> is "Copy Rectangle to Register". It will prompt you for a register number so it can save it for later.<br />
<br />
<code>C-x r g</code> is "Insert register". This will insert the contents of the given register, overwriting whatever happens to be within the target rectangle. (So make room)<br />
<br />
<code>C-x r k</code> is "Kill rectangle". Delete rectangle and save contents for:<br />
<br />
<code>C-x r y</code> is "Yank rectangle". This will insert the contents of<br />
the last killed rectangle.<br />
<br />
As with all Emacs modifier combos, you can type <code>C-x r C-h</code> to find out what keys are bound beginning with the <code>C-x r</code> prefix.<br />
<br />
=== Aligning code ===<br />
<br />
Emacs22 has a neat tool called: align-regexp. Select a region you want to align text within, M-x align-regexp, and type a regexp representing the alignment delimiter.<br />
<br />
For example, I often line up my Haddock comments:<br />
<br />
<haskell><br />
f :: a -- ^ does a<br />
-> Foo b -- ^ and b<br />
-> c -- ^ to c<br />
</haskell><br />
<br />
Select the region, and let the regexp be: <code>--</code><br />
<br />
<haskell><br />
f :: a -- ^ does a<br />
-> Foo b -- ^ and b<br />
-> c -- ^ to c<br />
</haskell><br />
<br />
Of course, this works for just about anything. Personally, I've globally bound it to <code>C-x a r</code>:<br />
<br />
<code>(global-set-key (kbd "C-x a r") 'align-regexp)</code>.<br />
<br />
=== Automatically building ===<br />
Emacs 21 has a package that can be installed (included by default in 22 and up) called 'FlyMake'; the idea is that as you are editing away, it occasionally calls the interpreter/compiler automatically and keeps track of whether the code works or not. You can fairly easily get it to work for Haskell as well; see [http://www.emacswiki.org/cgi-bin/wiki/FlymakeHaskell FlymakeHaskell] on the Emacs wiki.<br />
<br />
=== Emacs Integration with Hayoo ===<br />
<br />
My newly installed system would not allow me to hoogle what I wanted (no xmonad or xmonadcontrib in hoogle) so someone suggested Hayoo.<br />
<br />
<code><br />
(define-key haskell-mode-map (kbd "<f3>") (lambda()(interactive)(browse-url (format "http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s&start" (region-or-word-at-point)))))<br />
</code><br />
<br />
region-or-word-at-point is available in the thing-at-pt+.el library.<br />
<br />
Added 22-12-2008 - Promt for hayoo word<br />
<br />
<code><br />
(defun rgr/hayoo()<br />
(interactive)<br />
(let* ((default (region-or-word-at-point))<br />
(term (read-string (format "Hayoo for the following phrase (%s): "<br />
default))))<br />
(let ((term (if (zerop(length term)) default term)))<br />
(browse-url (format "http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s&start" term)))))<br />
<br />
<br />
(define-key haskell-mode-map (kbd "<f3>") (lambda()(interactive)(rgr/hayoo)))<br />
</code><br />
<br />
Alteratively use the excellent browse-apropos-url stuff:<br />
<br />
http://www.emacswiki.org/emacs/BrowseAproposURL#toc6<br />
<br />
[http://richardriley.net Richard]<br />
<br />
Note: Using and URL like this should work too and will give better results (not yet tested as I'm not an emacs user):<br />
<br />
<code><br />
http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s<br />
</code><br />
<br />
[[User:Tbh|Tbh]] 00:56, 25 January 2009 (UTC)<br />
<br />
=== Integration with HLint ===<br />
<br />
[http://www-users.cs.york.ac.uk/~ndm/hlint/ HLint] could be used directly from Emacs buffer. There is [http://www.cs.york.ac.uk/fp/darcs/hlint/data/hs-lint.el hs-lint.el] package (in HLint distribution, in the data subdirectory), that allows user to run HLint and navigate through errors, or apply suggestions to the source code.<br />
<br />
This package implements `hs-lint` command, that behaves differently depending on settings. If the `hs-lint-replace-with-suggestions` variable is set to `t`, then it will ask user and apply concrete suggested change to source code, otherwise you'll be able to navigate through list of suggestions with `next-error` command. If the `hs-lint-replace-without-ask` variable is also set to `t`, then all suggestions will applied automatically. <br />
<br />
You can also bind `hs-lint` command to some key (in this example this is `C-c l`) with following code:<br />
<br />
<code><br />
(defun my-haskell-mode-hook ()<br />
(local-set-key "\C-cl" 'hs-lint))<br />
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)<br />
</code><br />
<br />
All settings, described above are available for customization via `hs-lint` customization group.<br />
<br />
[[Category:Development tools]]</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=30163Template Haskell2009-09-22T07:51:58Z<p>RoelVanDijk: Removed mention of profiling bug; seems it was fixed on 06/21/06</p>
<hr />
<div>'''[http://www.haskell.org/th/ 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/~simonpj/papers/meta-haskell/ . It is [http://haskell.cs.yale.edu/ghc/docs/6.2/html/users_guide/template-haskell.html included] in GHC version 6. If you start working with Template Haskell you'll probably want to join the [http://haskell.org/mailman/listinfo/template-haskell Template Haskell mailing list].<br />
<br />
This page hopes to be a more central and organized repository of TH related things. However, at this point most things should probably go to/through the mailing list first.<br />
<br />
=What is Template Haskell?=<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 />
There is a [http://haskell.org/mailman/listinfo/template-haskell mailing list specifically for Template Haskell]. It's worth joining if you start to use TH.<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]<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/~simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper.<br />
* [http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell/Language-Haskell-TH.html The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
** http://www.haskell.org/bz/thdoc.htm<br />
** http://www.haskell.org/bz/th3.htm<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<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 />
* Papers about Template Haskell<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, May 2002. [http://haskell.org/th/papers/meta-haskell.ps [A4 ps]] [http://haskell.org/th/papers/meta-haskell.bib [bib]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003.[http://haskell.org/th/papers/Template_Haskell-A_Report_From_The_Field.ps [A4 ps]] [http://haskell.org/th/papers/Template_Haskell-A_Report_From_The_Field.bib [bib]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, May 2003.[http://haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.ps [A4 ps]][http://haskell.org/th/papers/Unrolling_and_Simplifying_Expressions_with_Template_Haskell.bib [bib]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [http://haskell.org/th/papers/hlpp.ps [A4 ps]][http://haskell.org/th/papers/hlpp.bib [bib]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [http://haskell.org/th/papers/th-pan.ps [A4 ps]] [http://haskell.org/th/papers/th-pan.bib [bib]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004.[http://haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.ps [A4 ps]][http://haskell.org/th/papers/Typing_Template_Haskell__Soft_Types.bib [bib]]<br />
<br />
= Other useful resources =<br />
<br />
* [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki?<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 />
*[http://web.comlab.ox.ac.uk/oucl/work/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
Feel free to update our Wikipedia entry<br />
http://en.wikipedia.org/wiki/Template_Haskell<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 seperate 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 exmples. - 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://cvs.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/th/papers.html 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://www-users.cs.york.ac.uk/~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 strictnes 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 />
* Write Haddock documentation for the Template Haskell library.<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<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 />
== 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"))<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 />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
= Examples =<br />
== Select from a tuple ==<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://www.haskell.org/th/papers/meta-haskell.ps 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 />
== 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 />
== Printf ==<br />
This example taken from: http://haskell.cs.yale.edu/ghc/docs/6.0/html/users_guide/template-haskell.html<br />
<br />
Build it using a command similar to one of the following (depending on your environment):<br />
<br />
ghc/compiler/stage3/ghc-inplace --make -fglasgow-exts -package haskell-src main.hs -o main.exe<br />
ghc --make -fth Main.hs -o printfTest<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
-- Import our template "pr"<br />
import Printf ( pr )<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "pr" and splices it into<br />
-- the argument of "putStrLn".<br />
main = putStrLn ( $(pr "Hello") )<br />
</haskell><br />
<br />
Printf.hs:<br />
<br />
<haskell><br />
module Printf where<br />
<br />
-- Skeletal printf from the paper.<br />
-- It 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.Syntax<br />
<br />
-- Describe a format string<br />
data Format = D | S | L String<br />
<br />
-- Parse a format string. This is left largely to you<br />
-- as we are here interested in building our first ever<br />
-- Template Haskell program and not in building printf.<br />
parse :: String -> [Format]<br />
parse s = [ L s ]<br />
<br />
-- Generate Haskell source code from a parsed representation<br />
-- of the format string. This code will be spliced into<br />
-- the module which calls "pr", at compile time.<br />
gen :: [Format] -> ExpQ<br />
gen [D] = [| \n -> show n |]<br />
gen [S] = [| \s -> s |]<br />
gen [L s] = stringE s<br />
<br />
-- Here we generate the Haskell code for the splice<br />
-- from an input format string.<br />
pr :: String -> ExpQ<br />
pr s = gen (parse s)<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 />
==[[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 />
[[Category:Language extensions]]</div>RoelVanDijkhttps://wiki.haskell.org/index.php?title=Concrete_view&diff=11956Concrete view2007-03-13T23:18:57Z<p>RoelVanDijk: Typo</p>
<hr />
<div>[[Category:Idioms]]<br />
It is sometimes not obvious how to implement an operation on some data structure. Using an intermediate [[concrete data type]] can help simplify the case analysis.<br />
<br />
==Simple example - complex numbers==<br />
Suppose you're implementing complex numbers (which you wouldn't do, since it's already in the standard library):<br />
<br />
<haskell><br />
data Complex = Complex Double Double<br />
<br />
instance Num Complex where<br />
(Complex r1 i1) + (Complex r2 i2) = Complex (r1+r2) (i1+i2)<br />
{- etc etc -}<br />
</haskell><br />
<br />
Some operations (e.g. complex roots) are easier in polar form. So make a "view" of your complex number type which projects the numbers into polar form:<br />
<br />
<haskell><br />
data ComplexPolarView = ComplexPolarView Double Double<br />
<br />
complexPolarView :: Complex -> ComplexPolarView<br />
complexPolarView (Complex r i) = {- detail omitted -}<br />
<br />
operationThatWouldBeEasierInPolarForm :: Complex -> Something<br />
operationThatWouldBeEasierInPolarForm c<br />
= case complexPolarView c of<br />
ComplexPolarView radius theta -> {- whatever -}<br />
</haskell><br />
<br />
==Use as a design tool==<br />
The technique is also valuable as a design tool. While trying to work out how a data type should be implemented, appropriate use of concrete views can help streamline the design process.<br />
<br />
A good example of this is due to [[User:RalfHinze]] in his paper, [http://www.informatik.uni-bonn.de/~ralf/publications/SearchTree.ps.gz A fresh look at binary search trees]. He notes that binary search tree deletion is much more difficult than insertion. His solution is to use a concrete view of the tree which simplifies the operation, and as a result, comes up with a new representation which makes the operation much easier to understand.<br />
<br />
Here is a simple binary search tree type:<br />
<br />
<haskell><br />
data Tree a = Leaf | Branch (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Suppose that we had a view of the binary search tree which looked like this:<br />
<br />
<haskell><br />
data TreeView a<br />
= EmptyTree<br />
| SingletonTree a<br />
| ConsTree (Tree a) (Tree a)<br />
<br />
treeView :: Tree a -> TreeView a<br />
</haskell><br />
<br />
And the following operations:<br />
<br />
<haskell><br />
-- Return the maximum value in the tree<br />
treeMax :: Tree a -> a<br />
<br />
-- These are the "converses" of the TreeView<br />
emptyTree :: Tree a<br />
singletonTree :: a -> Tree a<br />
consTree :: Tree a -> Tree a -> Tree a<br />
</haskell><br />
<br />
(The "converse" operations are basically [[smart constructor]]s.)<br />
<br />
Then you can implement tree insertion like this:<br />
<br />
<haskell><br />
insert :: (Ord a) => a -> Tree a -> Tree a<br />
insert x t<br />
= case treeView t of<br />
EmptyTree -> singletonTree x<br />
SingletonTree a<br />
| x < a -> consTree (singletonTree x) (singletonTree a)<br />
| x == a -> singletonTree x<br />
| x > a -> consTree (singletonTree a) (singletonTree x)<br />
ConsTree l r<br />
| x < treeMax l -> consTree (insert x l) r<br />
| otherwise -> consTree l (insert x r)<br />
</haskell><br />
<br />
And you could implement tree deletion like this:<br />
<br />
<haskell><br />
delete :: (Ord a) => a -> Tree a -> Tree a<br />
delete x t<br />
= case treeView t of<br />
EmptyTree -> emptyTree<br />
SingletonTree a<br />
| x == a -> emptyTree<br />
| otherwise -> singletonTree a<br />
ConsTree l r<br />
| x <= treeMax l -> consTree (delete x l) r<br />
| otherwise -> consTree l (delete x r)<br />
</haskell><br />
<br />
<br />
Implementing the view and the operations in terms of <hask>Tree</hask> is straightforward, and it allows you to start with a simple data structure and make it more sophisticated as needed. With the view, you can change the implementation of <hask>Tree</hask> without the algorithms changing. Basically, you're using an [[abstract data type]] within a module at the micro-design level.<br />
<br />
Once the algorithms have stabilised, then you can change your implementation (here of <hask>Tree</hask>) to be optimised for the view and operations and refactor out the abstraction layer if you want.<br />
<br />
In this case, redesigning the data structure is simple. Simply pull the maximum element out to the top level:<br />
<br />
<haskell><br />
data Tree a<br />
= Empty<br />
| NonEmpty (Tree' a) a<br />
<br />
data Tree' a<br />
= Leaf<br />
| Branch (Tree' a) a (Tree' a)<br />
<br />
treeView :: Tree a -> TreeView a<br />
treeView Empty = EmptyTree<br />
treeView (NonEmpty Leaf a) = SingletonTree a<br />
treeView (NonEmpty (Branch l x r) a) = ConsTree (NonEmpty l x) (NonEmpty r a)<br />
<br />
maxTree :: Tree a -> a<br />
maxTree (NonEmpty _ a) = a<br />
<br />
-- Implementing emptyTree, singletonTree and consTree are left as an exercise<br />
</haskell><br />
<br />
The <hask>TreeView</hask> data structure can then be refactored out if desired.<br />
<br />
==As part of a module interface==<br />
Concrete views are also valuable at the module interface level. Rather than providing a number of accessor functions to get data out of some type...<br />
<br />
<haskell><br />
module Complex (<br />
Complex,<br />
-- stuff omitted<br />
radius, theta<br />
) where<br />
<br />
radius :: Complex -> Double<br />
theta :: Complex -> Double<br />
<br />
{- etc etc -}<br />
</haskell><br />
<br />
...provide a concrete view instead.<br />
<br />
<haskell><br />
module Complex (<br />
Complex,<br />
-- stuff omitted<br />
ComplexPolarView(..),<br />
complexPolarView<br />
) where<br />
<br />
{- etc etc -}<br />
</haskell><br />
<br />
==Summary==<br />
If you needed more incentive, remember that Haskell data structures are lazily evaluated. Only as much of the view as the client needs will actually be computed, and if there is any shared work between different parts of the view, it will only be computed once. You can't say that about accessor functions.<br />
<br />
[[Views]] were briefly considered as a language extension, but never really caught on.<br />
<br />
[[User:AndrewBromage]]</div>RoelVanDijk