https://wiki.haskell.org/api.php?action=feedcontributions&user=CaleGibbard&feedformat=atom
HaskellWiki - User contributions [en]
2024-03-19T11:49:08Z
User contributions
MediaWiki 1.35.5
https://wiki.haskell.org/index.php?title=IRC_channel&diff=62986
IRC channel
2019-08-05T05:47:38Z
<p>CaleGibbard: fix link to IRC channel stats</p>
<hr />
<div>Internet Relay Chat is a worldwide text chat service with many thousands<br />
of users among various irc networks.<br />
<br />
The Freenode IRC network hosts the very large #haskell channel, and we've had<br />
up to 1046<br />
concurrent users, making the channel consistently<br />
[https://netsplit.de/channels/details.php?room=%23haskell&net=freenode one of the most popular]<br />
of the thousands of channels on freenode. One famous<br />
resident is [[Lambdabot]], another is [http://hpaste.org hpaste] (see<br />
the [[#Bots|Bots]] section below).<br />
<br />
The IRC channel can be an excellent place to learn more about Haskell,<br />
and to just keep in the loop on new things in the Haskell world. Many<br />
new developments in the Haskell world first appear on the irc channel.<br />
<br />
Since 2009, the Haskell channel has grown large enough that we've split it in two parts:<br />
<br />
* #haskell, for all the usual things<br />
* #haskell-in-depth , for those seeking in depth, or more theoretical discussion<br />
<br />
As always, #haskell remains the primary place for new user questions.<br />
<br />
{| border="0" align="right"<br />
|+ '''#haskell visualized'''<br />
|-<br />
| [[Image:Haskell-current.png|thumb|The social graph, Jan 2008]]<br />
| [[Image:Irc-raw.png|thumb|Daily traffic since 2004]]<br />
|-<br />
| [[Image:Nick-activity.png|thumb|Growth]]<br />
| [[Image:Haskell-wordle-irc.png|thumb|Noun map]]<br />
|}<br />
<br />
== Getting there ==<br />
<br />
If you point your irc client to [irc://chat.freenode.net/haskell chat.freenode.net] and then join the #haskell channel, you'll be there. Alternately, you can try http://webchat.freenode.net/ which connects inside the browser.<br />
<br />
Example, using [http://www.irssi.org/ irssi]:<br />
<br />
$ irssi -c chat.freenode.net -n myname -w mypassword<br />
/join #haskell<br />
<br />
Tip, if you're using Emacs to edit your Haskell sources then why not use it to chat about Haskell? Check out [http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient ERC], The Emacs IRC client. Invoke it like this and follow the commands:<br />
<br />
M-x erc-select<br />
...<br />
/join #haskell<br />
<br />
[[Image:Irc--haskell-screenshot.png|frame|A screenshot of an irssi session in #haskell]]<br />
<br />
== Principles ==<br />
<br />
The #haskell channel is a very friendly, welcoming place to hang out,<br />
teach and learn. The goal of #haskell is to encourage learning and<br />
discussion of Haskell, functional programming, and programming in<br />
general. As part of this we welcome newbies, and encourage teaching of<br />
the language.<br />
<br />
Part of the #haskell success comes from the fact that the community<br />
is quite tight knit &mdash; we know each other &mdash; it's not just a homework<br />
channel. As a result, many collaborative projects have arisen between<br />
Haskell irc channel citizens.<br />
<br />
To maintain the friendly, open culture, the following is required:<br />
<br />
* Low to zero tolerance for ridiculing questions. Insulting new users is unacceptable. New Haskell users should feel entirely comfortable asking questions.<br />
<br />
* Helpful answers should be encouraged with <code>name++</code> karma points, in public, as a reward for providing a good answer.<br />
<br />
* Avoid getting frustrated by negative comments and ambiguous questions. Approach them by asking for details (i.e. [http://en.wikipedia.org/wiki/Socratic_method Socratic questioning]), rather than challenging the competence of the writer (ad hominem). As the channel grows, we see a diverse range of people with different programming backgrounds getting accustomed to Haskell. Be patient and take satisfaction from spreading knowledge.<br />
<br />
== History ==<br />
<br />
The #haskell channel appeared in the late 90s, and really got going<br />
in early 2001, with the help of Shae Erisson (aka shapr).<br />
<br />
== Related channels ==<br />
<br />
In addition to the main Haskell channel there are also:<br />
<br />
=== Language/Country specific ===<br />
<br />
The Freenode staff have asked us to consolidate language channels into the "#haskell-" namespace rather than have them continue on in the "#haskell." namespace. Eventually the language channels below listed with "#haskell." will have to move.<br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="left"<br />
! Channel<br />
! Purpose<br />
|-<br />
| style="width: 20%;" | #haskell-br<br />
| Brazilian Portuguese (pt_BR) speakers<br />
|-<br />
| #haskell.cz<br />
| Czech speakers (UTF-8)<br />
|- <br />
| #haskell.de<br />
| German speakers<br />
|-<br />
| #haskell.dut<br />
| Dutch speakers<br />
|-<br />
| #haskell.es<br />
| Spanish speakers<br />
|-<br />
| #haskell.fi<br />
| Finnish speakers<br />
|-<br />
| #haskell-fr<br />
| French speakers (note the hyphen! in the channel name)<br />
|-<br />
| #haskell.hr<br />
| Croatian speakers<br />
|-<br />
| #haskell-id<br />
| Indonesian speakers (note the hyphen! in the channel name)<br />
|-<br />
| #haskell-it <br />
| Italian speakers (note the hyphen! in the channel name)<br />
|-<br />
| #haskell.jp <br />
| Japanese speakers<br />
|-<br />
| #haskell.scandinavian<br />
| Scandinavian speakers<br />
|-<br />
| #haskell-kr<br />
| Korean speakers<br />
|-<br />
| #haskell.no <br />
| Norwegian speakers<br />
|-<br />
| #haskell.pt<br />
| Portuguese speakers<br />
|-<br />
| #haskell-pl<br />
| Polish speakers<br />
|-<br />
| #haskell.ru <br />
| Russian speakers. Seems that most of them migrated to Jabber conference (haskell@conference.jabber.ru).<br />
|-<br />
| #haskell_ru <br />
| Russian speakers again, in UTF-8. For those, who prefer good ol' IRC channel with a lambdabot.<br />
|-<br />
| #haskell-ro<br />
| Romanian speakers.<br />
|-<br />
| #haskell.se <br />
| Swedish speakers<br />
|-<br />
| #haskell.tw<br />
| Chinese speakers (mainly in Taiwan)<br />
|-<br />
| #haskell.vn<br />
| Vietnamese speakers<br />
|-<br />
| #chicagohaskell<br />
| [http://chicagohaskell.com Chicago Haskell] programmers group<br />
|}<br />
<br />
=== Platform-specific ===<br />
{| border="1" cellspacing="0" cellpadding="5" align="left"<br />
! Channel<br />
! Purpose<br />
|-<br />
| style="width: 20%;" | #haskell-beginners<br />
| Haskell people focused on teaching and learning Haskell, not just beginners.<br />
|-<br />
| #haskell-offtopic<br />
| Haskell people talking about anything except Haskell itself (no TLS required)<br />
|-<br />
| #haskell-blah <br />
| Haskell people talking about anything except Haskell itself (TLS required)<br />
|-<br />
| #haskell-game<br />
| The hub for Haskell-based [[Game Development|game development]]<br />
|-<br />
| #haskell-in-depth<br />
| slower paced discussion of use, theory, implementation etc with no monad tutorials!<br />
|-<br />
| #haskell-iphone<br />
| Haskell-based [[iPhone]] development<br />
|-<br />
| #haskell-apple<br />
| projects that target iOS or OS X using Haskell. <br />
|-<br />
| #haskell-lisp<br />
| [[Haskell Lisp]] - projects that are creating Lisps written in Haskell, or Haskell implementations written in Lisps. <br />
|-<br />
| #haskell-llvm<br />
| For projects using Haskell and LLVM<br />
|-<br />
| #haskell-overflow<br />
| Overflow conversations<br />
|-<br />
| #haskell-web<br />
| Friendly, practical discussion of haskell web app/framework/server development<br />
|-<br />
| #haskell-robotics<br />
| Discussion about the use of Haskell for robotics applications.<br />
|-<br />
| #arch-haskell <br />
| [[Arch Linux]]/ specific Haskell conversations<br />
|-<br />
| #fedora-haskell<br />
| [[Fedora]] Haskell SIG<br />
|-<br />
| #gentoo-haskell <br />
| [[Gentoo]]/Linux specific Haskell conversations<br />
|}<br />
<br />
=== Projects using haskell ===<br />
{| border="1" cellspacing="0" cellpadding="5" align="left"<br />
! Channel <br />
! Purpose<br />
|-<br />
| style="width: 20%;" | #darcs <br />
| [[Darcs]] revision control system<br />
|-<br />
| #diagrams<br />
| [[Diagrams]] EDSL<br />
|-<br />
| #hackage<br />
| Haskell's software distribution infrastructure<br />
|-<br />
| #haskell-lens<br />
| [[Lens]] discussions<br />
|-<br />
| #haskell-stack<br />
| [https://github.com/commercialhaskell/stack/tree/master/doc Stack] discussions<br />
|-<br />
| #happs<br />
| [http://happstack.com Happstack] web framework<br />
|-<br />
| #hledger<br />
| [http://hledger.org hledger] accounting tools and library<br />
|-<br />
| #leksah<br />
| [http://leksah.org Leksah] IDE for Haskell development<br />
|-<br />
| #perl6 <br />
| [http://www.pugscode.org Perl 6] development (plenty of Haskell chat there too)<br />
|-<br />
| #snowdrift <br />
| [https://snowdrift.coop Snowdrift.coop] Yesod-based web platform for funding free/libre/open works, welcomes Haskell volunteer devs including beginners<br />
|-<br />
| #snapframework<br />
| [http://snapframework.com/ Snap] web framework<br />
|-<br />
| #xmonad<br />
| [http://xmonad.org Xmonad] tiling window manager<br />
|-<br />
| #yesod<br />
| [http://yesodweb.com Yesod] web framework<br />
|-<br />
| #yampa<br />
| [https://wiki.haskell.org/Yampa Yampa] Arrowized FRP<br />
|}<br />
<br />
== Logs ==<br />
<br />
'''Logs''' are kept at http://tunes.org/~nef/logs/haskell/ and can be searched at http://ircbrowse.net/browse/haskell<br />
<br />
<!-- anywhere else? ircbrowse.com is a goner, apparently --><br />
<br />
== Bots ==<br />
<br />
There are various bots on the channel. Their names and usage are described here.<br />
<br />
=== lambdabot ===<br />
<br />
[[Lambdabot]] is both the name of a software package and a bot on the channel. It provides many useful services for visitors to the IRC channel. It is available as a haskell package and can be integrated into ghci. Details on the software are found on a [[Lambdabot|separate wiki page]].<br />
<br />
Here is its interface for the IRC user:<br />
<br />
lambdabot's commands are prepended by a '@' sign.<br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Command<br />
! Usage<br />
|-<br />
| @help<br />
| display help to other commands, but help text is not available for all commands.<br />
|-<br />
| @type EXPR or ':t' EXPR<br />
| shows the type of an expression<br />
|-<br />
| @kind TYPECONSTRUCTOR<br />
| shows the kind of a type constructor<br />
|-<br />
| @run EXPR or '>' EXPR<br />
| evaluates EXPR<br />
|-<br />
| @pl FUNCTION<br />
| shows a [[pointfree]] version of FUNCTION<br />
|-<br />
| @pointful FUNCTION or '@unpl' FUNCTION<br />
| shows a 'pointful' version of FUNCTION<br />
|-<br />
| @tell <nick> <msg> -- same as @ask<br />
| Next time <nick> speaks in channel they will be notified they have a message pending and how to receive it.<br />
|}<br />
<br />
=== preflex ===<br />
<br />
is the name of a lambdabot with more commands/plugins enabled. It is run by ?? To talk to preflex, write <tt>preflex: command ARGS</tt><br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Command<br />
! Usage<br />
|-<br />
| help COMMAND<br />
| displays help to other commands.<br />
|-<br />
| list<br />
| lists all plugins with their commands<br />
|-<br />
| NICK++ / NICK--<br />
| in/decrements the karma of NICK.<br />
|-<br />
| karma NICK<br />
| shows the karma of NICK<br />
|-<br />
| seen NICK<br />
| shows information about the last message of a user<br />
|-<br />
| tell / ask<br />
| sends NICK MSG a message when she becomes active.<br />
|-<br />
| xseen<br />
| ''see 'seen' ?? any difference ?''<br />
|-<br />
| quote NICK<br />
| prints a random quote of NICK<br />
|-<br />
| remember NAME QUOTE<br />
| associates NAME with quote. can be accessed by 'quote'<br />
|-<br />
| ...<br />
| ...<br />
|}<br />
<br />
=== hpaste ===<br />
The hpaste bot provides a notification interface to the [http://hpaste.org hpaste pastebin]. [[Hpaste.el|Emacs integration]] is available.<br />
<br />
''Usage?''<br />
<br />
''Not online often !? ''<br />
<br />
=== hackage ===<br />
The hackage bot provides real-time notifications of new package uploads to [http://hackage.haskell.org Hackage].<br />
<br />
== Locations ==<br />
<br />
To get an overview of where everybody on the channel might<br />
be, physically, please visit [[Haskell user locations]].<br />
<br />
<br />
[[Category:Community]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Xmonad/General_xmonad.hs_config_tips&diff=62901
Xmonad/General xmonad.hs config tips
2019-04-12T02:13:57Z
<p>CaleGibbard: /* Adding your own keybindings */ fix EZConfig link</p>
<hr />
<div>[[Category:XMonad configuration]]<br />
<br />
This document assumes you're running >= XMonad-0.8.<br />
<br />
It describes general tips for configuring xmonad.hs, for example "How to make window ''X'' float by default" and others. If you can't find what you're searching for, you may want to look at the [[Xmonad/Config_archive|Config archive]] or ask for help on #xmonad@irc.freenode.net. <br />
<br />
Also useful, for an overview of how to configure bindings and hooks, and (somewhat out of date) summary of xmonad-contrib extensions, see [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Doc-Extending.html XMonad.Doc.Extending].<br />
<br />
Please add what you found useful, and of course improving existing tips or adding alternatives is highly appreciated!<br />
<br />
== Managing Windows aka Manage Hooks ==<br />
<hask>ManageHook</hask>s define special actions to be performed on newly created windows matching specific properties.<br />
<br />
=== Making window float by default, or send it to specific workspace ===<br />
====ManageHook examples====<br />
This example shifts '''Rhythmbox''' to workspace <tt>"="</tt> and '''XDvi''' to <tt>"7:dvi"</tt>, floats '''Xmessage''', and uses <hask>manageDocks</hask> to make docks visible on all workspaces. All this is combined with the default XMonad <hask>manageHook</hask>. [[Xmonad/Config_archive/John_Goerzen%27s_Configuration|This step-by-step tutorial]] covers initially setting up a <hask>manageHook</hask>, too.<br />
<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.ManageDocks<br />
import XMonad.Util.EZConfig<br />
-- module imports and other top level definitions<br />
<br />
myManageHook = composeAll<br />
[ className =? "Rhythmbox" --> doShift "="<br />
, className =? "XDvi" --> doShift "7:dvi"<br />
, className =? "Xmessage" --> doFloat<br />
, manageDocks<br />
]<br />
<br />
main = xmonad $ defaultConfig<br />
{ workspaces = ["1:dev","2:mail","3:web","4:comm","5:ham","6:tmp","7:dvi","8","9","0","-","="]<br />
, manageHook = myManageHook <+> manageHook defaultConfig -- uses default too<br />
-- set terminal, modMask, etc.<br />
} `additionalKeysP` myKeys<br />
</haskell><br />
<br />
This example sends '''Firefox''' to workspace <tt>"web"</tt> when it starts. '''Gajim''' gets sent to workspace <tt>"jabber"</tt>. Finally, it floats '''Firefox''' dialog windows, '''Gajim''' and '''Xmessage''' windows, and windows with <tt>Google</tt> or <tt>Pidgin</tt> as any part of the class name; likewise, any window with <tt>VLC</tt> anywhere in its title.<br />
<haskell><br />
-- Data.List provides isPrefixOf isSuffixOf and isInfixOf<br />
import Data.List <br />
--<br />
myManageHook = composeAll . concat $<br />
[ [ className =? "Firefox-bin" --> doShift "web" ]<br />
, [ className =? "Gajim.py" --> doShift "jabber" ]<br />
, [(className =? "Firefox" <&&> resource =? "Dialog") --> doFloat]<br />
<br />
-- using list comprehensions and partial matches<br />
, [ className =? c --> doFloat | c <- myFloatsC ]<br />
, [ fmap ( c `isInfixOf`) className --> doFloat | c <- myMatchAnywhereFloatsC ]<br />
, [ fmap ( c `isInfixOf`) title --> doFloat | c <- myMatchAnywhereFloatsT ]<br />
]<br />
-- in a composeAll hook, you'd use: fmap ("VLC" `isInfixOf`) title --> doFloat<br />
where myFloatsC = ["Gajim.py", "Xmessage"]<br />
myMatchAnywhereFloatsC = ["Google","Pidgin"]<br />
myMatchAnywhereFloatsT = ["VLC"] -- this one is silly for only one string!<br />
</haskell><br />
<br />
Here's another example using both classes and titles:<br />
<haskell><br />
myManageHook :: ManageHook<br />
myManageHook = composeAll . concat $<br />
[ [ title =? t --> doFloat | t <- myTitleFloats]<br />
, [ className =? c --> doFloat | c <- myClassFloats ] ]<br />
where<br />
myTitleFloats = ["Transferring"] -- for the KDE "open link" popup from konsole<br />
myClassFloats = ["Pinentry"] -- for gpg passphrase entry<br />
</haskell><br />
<br />
====Shift an app to a workspace and view it====<br />
The following will put new '''FocusMeNow''' windows on the <tt>"doc"</tt> workspace and also <hask>greedyView</hask> that workspace.<br />
<haskell><br />
import Control.Monad (liftM2)<br />
<br />
myManageHook = composeAll<br />
[ className = "FocusMeNow" --> viewShift "doc"<br />
-- more hooks<br />
]<br />
where viewShift = doF . liftM2 (.) W.greedyView W.shift<br />
</haskell><br />
<br />
====Floating all new windows====<br />
To float all windows and manually tile them with <em>&lsaquo;mod&rsaquo;-</em>t, simply add <hask> <+> doFloat</hask> to your manage hooks. ''Warning:'' you don't want to combine this with hooks such as <hask>doF W.swapDown</hask> which put new windows below others. Also, the floating layer isn't designed for extensive use; if possible, limit <hask>doFloat</hask> to apps that really need it (see examples in previous section.)<br />
<haskell><br />
-- skipped<br />
main = xmonad defaultConfig<br />
{ manageHook = myManageHooks <+> doFloat<br />
-- more changes<br />
}<br />
</haskell><br />
<br />
==== Making windows unfloat ====<br />
A related task is - how do I unfloat windows of a particular class or name? See the <hask>unfloat</hask> hook defined in the following example:<br />
<br />
<haskell><br />
-- A manageHook to float everything by default and unfloat a few windows<br />
myManageHook :: ManageHook<br />
myManageHook = composeAll [ className =? "defcon.bin.x86" --> unfloat,<br />
className =? "Darwinia" --> unfloat ]<br />
<+> doFloat <+> manageDocks<br />
where unfloat = ask >>= doF . W.sink<br />
</haskell><br />
<br />
====More info about ManageHooks====<br />
See the FAQ about [[Xmonad/Frequently asked questions#I need to find the class title or some other X property of my program|using xprop]] to get the <hask>className</hask>, <hask>appName</hask>, <hask>title</hask> or other string properties of windows.<br />
<br />
See also the [http://xmonad.org/xmonad-docs/xmonad/XMonad-ManageHook.html documentation for ManageHook] or the ManageHook section in <br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Doc-Extending.html#15 Extending XMonad].<br />
<br />
=== Gimp ===<br />
The most popular Gimp setups with xmonad are the default of floating all Gimp windows, or using two nested [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IM.html Layout.IM] modifiers to put the toolbox and dock panels to either side of some other layout like [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Tabbed.html tabbed] or <hask>(MyFavoriteTilingLayout ||| Full)</hask>, plus usually floating tool dialogs with <hask>manageHook</hask>s. Some people combine the toolbox and dock into a single panel. See [[#Tiling most windows in gimp|sample configs]] below.<br />
<br />
====Gimp windows as seen by xmonad====<br />
To choose how to work with the Gimp in XMonad, it's helpful to understand<br />
the different types of windows as XMonad sees them. If you just want<br />
some example setups, skip to the next section.<br />
<br />
* '''All Gimp windows''', i.e. those with <tt>WM_CLASS</tt> class of <tt>"Gimp"</tt>. These windows float if you have <hask>manageHook defaultConfig</hask> anywhere in your <hask>manageHook</hask>. You probably ''don't'' want this if you plan to tile even the Gimp tool setting dialogs. Otherwise keep the <hask>manageHook defaultConfig</hask>, and only unfloat the <tt>gimp-toolbox</tt>, <tt>gimp-image-window</tt>, and possibly <tt>gimp-dock</tt>.<br />
<br />
* '''Transient or fixed size windows''', like file open, ok/cancel, fixed size tool dialogs, etc. XMonad floats these by default for all applications, even ''without'' using <hask> manageHook defaultConfig</hask>. If you ''really'' want to, you can unfloat specific transients or fixed size windows -- see [[#Making_windows_unfloat|unfloat]] above.<br />
<br />
* '''Gimp toolbox or dock(s)''', matched with <tt>WM_WINDOW_ROLE(STRING)</tt> to use <hask>layoutHook</hask>s or <hask>manageHook</hask>s to place and manage them. Also, with drag and drop you can combine or separate their tabs and panes into one or more windows depending on how you want to use them.<br />
<br />
:On startup, a default Gimp install creates (1) an empty image window, (2) the '''toolbox''' window (brushes, eraser, etc. and their options), and (3) a single '''dock''' (layers, paths, etc.) Customize them by dragging tabs to and from existing panels or onto the "create panel separator" on either type of window, (it will highlight when a dragged tab is over it). (It's just below the fg/bg color swatches on the toolbox window.)<br />
<br />
* '''Gimp tool windows''', matched by suffix <tt>"tool"</tt> with <tt>WM_WINDOW_ROLE(STRING)</tt>. (Or with darcs XMonad (0.9) or XMonad 0.10, use <hask>isDialog</hask> from [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html ManageHelpers]). These are the many tool settings popups like Levels, Threshold, Curves that normally don't have toolbox tabs. Most people probably want these floated; below is an example of how to do it if you're not starting from all gimp windows being floated.<br />
<br />
====Tiling most windows in Gimp====<br />
A good way to work with the Gimp in XMonad is to tile most windows with <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ResizableTile.html resizableTall]</tt>, <tt>[http://xmonad.org/xmonad-docs/xmonad/XMonad-Layout.html#t:Full Full]</tt>, [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Tabbed.html tabbed] (or several layout choices separated by <hask>|||</hask>) in the center of the screen, and....<br />
<br />
Use <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IM.html withIM]</tt>, nested <hask>withIM</hask>s, or <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutCombinators.html XMonad.Layout.LayoutCombinators]</tt> to tile your toolbox, combined toolbox and dock, or separate toolbox and dock(s) at the screen edges. As needed, float or unfloat windows by role, or by using <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html#v:isDialog Hooks.ManageHelpers.isDialog]</tt> from [http://hackage.haskell.org/package/xmonad-contrib xmonad-contrib].<br />
<br />
(See also [[#Gimp windows as seen by xmonad|Gimp windows section]].)<br />
<br />
To use nested <hask>withIM</hask>s to have the toolbox and dock treated separately, see [http://nathanhowell.net/2009/03/08/xmonad-and-the-gimp/ Nathan Howell's blog post about XMonad and the Gimp].<br />
<br />
:[[Image:Xmonadgimp.jpg|220px]]<br />
<br />
If the property matching doesn't seem to be working correctly, check class or role with xprop. See [[Xmonad/Frequently_asked_questions#I_need_to_find_the_class_title_or_some_other_X_property_of_my_program| Using xprop to find an X property]].<br />
<br />
Here are some sample Gimp related <hask>manageHook</hask> snippets.<br />
<br />
;For people using <hask>manageHook defaultConfig</hask> or <hask>className =? "Gimp"</hask>:<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
<br />
myManageHook = composeAll<br />
[ (role =? "gimp-toolbox" <||> role =? "gimp-image-window") --> (ask >>= doF . W.sink)<br />
-- Note: hooks earlier in this list override later ones, so put the<br />
-- role hooks earlier than 'className =? "Gimp" ...' if you use both.<br />
<br />
-- other skipped manageHooks...<br />
]<br />
where role = stringProperty "WM_WINDOW_ROLE"<br />
</haskell><br />
<br />
;For people ''not'' using <hask>manageHook defaultConfig</hask> or <hask>className =? "Gimp"</hask>:<br />
<haskell><br />
import XMonad<br />
import Data.List -- for `isSuffixOf`<br />
-- etc<br />
<br />
myManageHook = composeAll<br />
[ -- other manageHooks<br />
, className =? "Gimp-2.6" --> doShift "*" -- may be "Gimp" or "Gimp-2.4" instead<br />
, (className =? "Gimp-2.6" <&&> fmap ("tool" `isSuffixOf`) role) --> doFloat<br />
]<br />
where role = stringProperty "WM_WINDOW_ROLE"<br />
</haskell><br />
<br />
If you use a <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Tabbed.html Tabbed]</tt> or <tt>[http://xmonad.org/xmonad-docs/xmonad/XMonad-Layout.html#t:Full Full]</tt> layout as your main layout and get unwanted focus shifts using <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IM.html#v:withIM withIM]</tt>, instead try <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutCombinators.html LayoutCombinators]</tt> or <tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ComboP.html ComboP]</tt>, or one of the other layout combiners in xmonad-0.9 and later. Also, make sure you're using <tt>[http://xmonad.org/xmonad-docs/xmonad/XMonad-StackSet.html#v:shiftMaster shiftMaster]</tt> instead of <tt>[http://xmonad.org/xmonad-docs/xmonad/XMonad-StackSet.html#v:swapMaster swapMaster]</tt> in your key and mouse bindings (<hask>swapMaster</hask> was the old default before xmonad-0.9, and some people may still have it in <tt>xmonad.hs</tt>.)<br />
<br />
Also, instead of picking the <hask>Full</hask>/<hask>Tabbed</hask> window with <em>&lsaquo;mod&rsaquo;-&lsaquo;tab&rsaquo;</em>, you can add the following to your mouse bindings, to be able to roll the mouse wheel over the Gimp toolbox until the correct window is focused, which seems to prevent the shifting around:<br />
<haskell><br />
import XMonad.Actions.FlexibleManipulate as Flex<br />
<br />
-- optional. but nicer than normal mouse move and size<br />
, ((mod4Mask, button3), Flex.mouseWindow Flex.discrete)<br />
-- scroll wheel window focusing<br />
, ((mod4Mask, button4), const $ windows W.swapDown)<br />
, ((mod4Mask, button5), const $ windows W.swapUp)<br />
</haskell><br />
<br />
;To use draggable width (<tt>[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-DragPane.html DragPane]</tt> combining <hask>Full</hask> and <hask>Tabbed</hask>) to put a single combined toolbox and dock to the right side of the screen:<br />
<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.ManageDocks<br />
import XMonad.Layout.NoBorders (smartBorders)<br />
import XMonad.Layout.DragPane<br />
import XMonad.Layout.LayoutCombinators hiding ((|||))<br />
import XMonad.Layout.Tabbed<br />
<br />
myLayoutHook = avoidStruts . smartBorders $<br />
Tall 1 (3 / 100) (1 / 2) ||| tabbedLayout ||| Full ||| gimpLayout<br />
where<br />
tabbedLayout = tabbedBottomAlways shrinkText defaultTheme<br />
gimpLayout = tabbedLayout ****||* Full<br />
</haskell><br />
<br />
:[[Image:AmphiGimpDragCombo.png|220px]]<br />
<br />
;To use <hask>withIM</hask> and a specific workspace (<tt>"*"</tt> here) for the Gimp:<br />
<br />
<haskell><br />
-- etc<br />
import XMonad.Layout.IM<br />
import XMonad.Layout.PerWorkspace<br />
import XMonad.Layout.ResizableTile -- Actions.WindowNavigation is nice too<br />
import XMonad.Util.EZConfig -- or use another method of binding resizable keys<br />
<br />
main = xmonad $ defaultConfig<br />
{ modMask = mod4Mask<br />
-- make sure to use the same workspace Id in workspaces, doShift, and onWorkspace<br />
, workspaces = ["a","b","c","d","e","f","g","*","i"]<br />
-- etc<br />
, manageHook = myManageHook<br />
-- note: the default manageHook floats gimp, so do not <+> manageHook defaultConfig<br />
, layoutHook = myLayouts<br />
} `additionalKeysP` myKeys<br />
<br />
myKeys = -- resize both axes in resizableTall<br />
[ ("M-C-k", sendMessage $ MirrorExpand)<br />
, ("M-C-j", sendMessage $ MirrorShrink)<br />
, ("M-C-h", sendMessage $ Shrink)<br />
, ("M-C-l", sendMessage $ Expand)<br />
]<br />
<br />
myLayoutHook =<br />
onWorkspace "*" gimpLayout $<br />
layoutHook defaultConfig -- layouts to use on other workspaces<br />
where<br />
gimpLayout = withIM (11/64) (Role "gimp-toolbox") $ ResizableTall 2 (1/118) (11/20) [1] ||| Full<br />
<br />
-- other variations<br />
--where<br />
-- mainLayouts = layoutHook defaultConfig<br />
-- gimpLayout = avoidStruts $ withIM (11/64) (Role "gimp-toolbox") $ mainLayouts<br />
-- gimpLayout = Full ||| (avoidStruts $ withIM (11/64) (Role "gimp-toolbox") $ ResizableTall 2 (1/118) (11/20) [1])<br />
-- etc<br />
</haskell><br />
<br />
=== Starting an app on more than one workspace ===<br />
To start emacs on workspaces 2, 3, and 4, for example, use something like the following in your manage hook:<br />
<haskell><br />
-- etc<br />
import XMonad.Actions.CopyWindow<br />
<br />
myManageHook = composeAll<br />
[ className =? "Emacs" --> (ask >>= doF . \w -> (\ws -> foldr ($) ws (copyToWss ["2","4"] w) ) . W.shift "3" ) :: ManageHook<br />
, resource =? "kdesktop" --> doIgnore<br />
]<br />
where copyToWss ids win = map (copyWindow win) ids -- TODO: find method that only calls windows once<br />
</haskell><br />
<br />
=== Ignoring a client (or having it sticky) ===<br />
You can have the position and geometry of a client window respected, and have that window <br />
be sticky, by ignoring it when it is created:<br />
<haskell><br />
main = xmonad $ defaultConfig<br />
{<br />
--<br />
, manageHook = manageHook defaultConfig<br />
<+><br />
(className =? "XClock" --> doIgnore)<br />
--<br />
}<br />
</haskell><br />
Would let xclock be sticky, and have its geometry respected.<br />
<br />
In >xmonad-0.8, the XMonad.Layout.Monitor offers some useful functions for managing such windows as well.<br />
<br />
=== Matching specific windows by setting the resource name or class ===<br />
<br />
Sometimes, instead of matching a program's resource name or window class, it is useful to change the program's name and/or class to something easier to detect. This is most useful when starting programs inside terminal emulators, but can also be used to distinguish between, say, editor sessions.<br />
<br />
Most X11 programs allow you to specify their resource name and/or class. Usually it's not possible to do so down to the level of individual windows, so you are likely to require <tt>[[Xmonad/Frequently_asked_questions#What_about_other_properties.2C_such_as_WM_WINDOW_ROLE.3F|WM_WINDOW_ROLE]]</tt> for that. Note that Java-based programs do not support any useful way to set either resource name or window class ([http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6528430 bug 6528430]).<br />
<br />
==== Gnome and KDE ====<br />
<br />
All Gnome and KDE programs support <tt>--name=</tt> and <tt>--class=</tt> options to specify the resource name and class for windows opened by those programs. Use the <tt>--help-all</tt> option to see these and other low-level options not normally visible.<br />
<br />
===== Terminal emulator factories =====<br />
<br />
<tt>gnome-terminal</tt> by default starts a single back-end "factory" and spawns terminal windows from it; all of these windows will share the same resource name and class. Use the <tt>--disable-factory</tt> option with <tt>--name=</tt> or <tt>--class=</tt> to ensure that the created window is not shared with unrelated terminals.<br />
<br />
Other terminal emulators for Gnome and KDE are likely to behave similarly. ('''[http://userbase.kde.org/Konsole Konsole]''' does not, at least as of this writing; but it does send itself to the background, which will break '''[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-SpawnOn.html XMonad.Actions.SpawnOn]''' unless you use the <tt>--nofork</tt> option.) Look for options to disable shared sessions or factories.<br />
<br />
==== Xt (Xaw, Motif) applications ====<br />
<br />
Programs such as <tt>xterm</tt> and the <tt>rxvt</tt> family of terminal emulators use the standard X11 Xt toolkit, and accept standard toolkit options ("<tt>man 7 X</tt>"; see the '''OPTIONS''' section). Specifically of interest here is the <tt>-name</tt> option. You cannot set the window class; this is fixed by the toolkit to a constant string supplied by the application developer (see <tt>XrmInitialize()</tt>).<br />
<br />
===== urxvtc and urxvtd =====<br />
<br />
This combination uses a single backend (<tt>urxvtd</tt>) which is asked to open terminal windows by <tt>urxvtc</tt>. These windows will share the same resource name. However, you can use <tt>-name</tt> to change the resource name of any individual window spawned by <tt>urxvtc</tt>.<br />
For example:<br />
<br />
urxvtc -name weechat -e weechat-curses<br />
<br />
The new resource name will be the first component of the WM_NAME property when listed using <tt>xprop</tt>:<br />
<br />
...<br />
WM_CLASS(STRING) = "weechat", "URxvt"<br />
...<br />
WM_NAME(STRING) = "weechat 0.4.1"<br />
<br />
Then you can match the new resource name in the <tt>manageDocks</tt> section of your config file, for example, to move that window running <tt> weechat-curses</tt> to a specific workspace:<br />
<br />
<haskell><br />
, resource =? "weechat" --> doShiftAndGo "7:irc"<br />
</haskell><br />
<br />
===== Caveat =====<br />
<br />
Programs using the standard X11 toolkit use the resource name and class to read configuration information from the app-defaults database and <tt>~/.Xresources</tt>. Be careful when changing the resource name to insure that it is not being used to select specific configuration information, or copy that configuration information to the new resource name you are using.<br />
<br />
==== Gtk+ and Qt ====<br />
<br />
Gtk+ and Qt programs are encouraged but not required to support <tt>--name</tt> and <tt>--class</tt> as specified in [[#Gnome_and_KDE|Gnome and KDE]] above. Unfortunately, if a given program doesn't support the standard options, it probably doesn't provide any way to control its resource name or class.<br />
<br />
==== Emacs ====<br />
<br />
When Emacs has been built with support for X11, both <tt>-name</tt> and <tt>--name</tt> options should work regardless of the X11 toolkit used. If Emacs only supports running in a terminal, you will need to control the terminal used to run it instead (e.g. <tt>"xterm -n myeditor -e emacs somefile"</tt>.)<br />
<br />
==== Firefox ====<br />
<br />
As of 2013-03-08, Firefox is abusing the ICCCM (it is technically legal because the ICCCM does not explicitly say it is wrong, it "only" strongly implies it by describing how windows should work on POSIX systems) and changing the resource name for its download manager window to <tt>"Download"</tt>. This means that you cannot match the download manager window for a custom Firefox instance.<br />
<br />
== Key and Mouse Bindings ==<br />
=== Adding your own keybindings ===<br />
<br />
This adds Mod-x keybinding for running ''xlock''.<br />
<haskell><br />
import qualified Data.Map as M<br />
--<br />
<br />
main = xmonad $ defaultConfig {<br />
--<br />
, keys = \c -> mykeys c `M.union` keys defaultConfig c<br />
--<br />
}<br />
where<br />
mykeys (XConfig {modMask = modm}) = M.fromList $<br />
[ ((modm , xK_x), spawn "xlock") ]<br />
</haskell><br />
For a list of the identifiers used for various keys, see<br />
[http://hackage.haskell.org/packages/archive/X11/1.4.5/doc/html/Graphics-X11-Types.html Graphics.X11.Types] and ExtraTypes.<br />
<br />
Also, the [http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Util-EZConfig.html Util.EZConfig] extension allows adding keybindings with simpler syntax, and even creates submaps for sequences like, e.g. "mod-x f" to launch firefox. You can use normal xmonad keybinding lists with its additionalKeys function, or with additionalKeysP, the bindings look like this:<br />
<haskell><br />
-- other imports<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
main = xmonad $ defaultConfig {<br />
terminal = "urxvt"<br />
, modMask = mod4Mask<br />
}<br />
`additionalKeysP`<br />
[ ("M-<Up>", windows W.swapUp)<br />
, ("M-x f", spawn "firefox")<br />
]<br />
`additionalMouseBindings`<br />
[ ((mod4Mask, button3), (\w -> focus w >> Flex.mouseResizeWindow w))<br />
, ((mod4Mask, button4), (\_ -> windows W.focusUp ))<br />
, ((mod4Mask, button5), (\_ -> windows W.focusDown))<br />
]<br />
</haskell><br />
<br />
This is also described in [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Doc-Extending.html#9]<br />
<br />
=== Adding your own mouse bindings ===<br />
Adding your own mouse bindings is explained in<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Doc-Extending.html#13]<br />
Also see the EZConfig example above.<br />
<br />
If you have a mouse with more than 5 buttons you can simply use '6'<br />
instead of 'button6' which isn't defined.<br />
<br />
e.g. with<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-EZConfig.html EZConfig]:<br />
<br />
,((0, 6), (\w -> focus w >> windows W.swapMaster))<br />
<br />
=== Displaying keybindings with dzen2 ===<br />
Sometimes, trying different xmonad.hs files, or while dialing in custom key bindings it can be nice to have a reminder of what does what. Of course, just editing or grepping the xmonad.hs is one solution, but for a nice colourized output, try adapting a script like this to your needs:<br />
<br />
<pre><br />
fgCol=green4<br />
bgCol=black<br />
titleCol=green4<br />
commentCol=slateblue<br />
keyCol=green2<br />
XCol=orange3<br />
startLine=3<br />
( echo " ^fg($titleCol) ----------- keys -----------^fg()";<br />
egrep 'xK_|eys' ~/.xmonad/xmonad.hs | tail -n +$startLine \<br />
| sed -e 's/\( *--\)\(.*eys*\)/\1^fg('$commentCol')\2^fg()/' \<br />
-e 's/((\(.*xK_.*\)), *\(.*\))/^fg('$keyCol')\1^fg(), ^fg('$XCol')\2^fg()/' <br />
echo '^togglecollapse()';<br />
echo '^scrollhome()' ) | dzen2 -fg $fgCol -bg $bgCol -x 700 -y 36 -l 22 -ta l -w 900 -p<br />
</pre><br />
<br />
Then bind a key to '''<hask>spawn "/path/to/my/showKeysScript"</hask>'''. While there's plenty of room for improvement in the parsing, this is fine for a quick and dirty display of normal or additionalKeys style bindings. It obviously would need to be changed to parse additionalKeysP style. To have comments displayed, note that it looks for indented comments containing 'eys' so use "Keys" or "keys" in " --" style comments to create keybinding subsections.<br />
<br />
Note that in older versions of dzen ^togglecollapse() and ^scrollhome() may not yet be supported. Use something like the following in dzen command line to get similar result:<br />
<br />
<pre><br />
-e 'onstart=togglecollapse,scrollhome;<br />
entertitle=uncollapse,grabkeys;<br />
enterslave=grabkeys;leaveslave=collapse,ungrabkeys;<br />
button2=togglestick;button3=exit:13;<br />
button4=scrollup;button5=scrolldown;<br />
key_Escape=ungrabkeys,exit'<br />
</pre><br />
<br />
[[image: Showkeys.png|220px]]<br />
<br />
=== Binding to the numeric keypad ===<br />
<br />
Bind to the non-numeric versions of these keys. They work<br />
regardless of NumLock status. To avoid conflicts with other apps<br />
you probably want to use them with modifiers. Here is an example<br />
of using them to navigate workspaces in the usual mod-N mod-shift-N<br />
way, but on the key pad:<br />
<br />
<haskell><br />
-- other imports<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
myWorkspaces = ["1","2","3","4","5","6","7","8","9","0"]<br />
<br />
modm = mod4Mask -- win key for mod<br />
<br />
myKeys = -- use with EZConfig.additionalKeys or edit to match your key binding method<br />
[<br />
-- more custom keybindings<br />
]<br />
++<br />
[((m .|. modm, k), windows $ f i)<br />
| (i, k) <- zip myWorkspaces numPadKeys<br />
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]<br />
]<br />
<br />
-- Non-numeric num pad keys, sorted by number <br />
numPadKeys = [ xK_KP_End, xK_KP_Down, xK_KP_Page_Down -- 1, 2, 3<br />
, xK_KP_Left, xK_KP_Begin, xK_KP_Right -- 4, 5, 6<br />
, xK_KP_Home, xK_KP_Up, xK_KP_Page_Up -- 7, 8, 9<br />
, xK_KP_Insert] -- 0<br />
</haskell><br />
<br />
=== Binding Workspaces on Function Keys ===<br />
'''With default key binding method or EZConfig.additionalKeys'''<br />
<br />
<haskell><br />
-- other imports<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
-- 'zip' will only bind as many keys as there are workspaces so define some more<br />
myWorkspaces = map show [1..12]<br />
<br />
modm = mod4Mask -- win key for mod<br />
<br />
main = xmonad $ defaultConfig<br />
{ workspaces = myWorkspaces<br />
} `additionalKeys` myKeys<br />
<br />
myKeys =<br />
[<br />
-- more custom keybindings<br />
]<br />
++<br />
[((m .|. modm, k), windows $ f i)<br />
| (i, k) <- zip myWorkspaces [xK_F1..xK_F12]<br />
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]<br />
]<br />
</haskell><br />
<br />
'''With EZConfig.additionalKeysP''' use something like the following myKeys instead:<br />
<br />
<haskell><br />
myKeys =<br />
[<br />
-- other "M-C-z" style keys<br />
]<br />
++<br />
[ (otherModMasks ++ "M-" ++ key, action tag)<br />
| (tag, key) <- zip myWorkspaces (map (\x -> "<F" ++ show x ++ ">") [1..12])<br />
, (otherModMasks, action) <- [ ("", windows . W.greedyView) -- or W.view<br />
, ("S-", windows . W.shift)]<br />
]<br />
</haskell><br />
<br />
For reference, the individual bindings assembled by the above list comprehensions look like this:<br />
<br />
<haskell><br />
-- default or additionalKeys style:<br />
-- skipped<br />
, ((modm, xK_F12), windows $ W.greedyView "12")<br />
, ((shiftMask .|. modm, xK_F1), windows $ W.shift "1")<br />
-- etc<br />
<br />
-- additionalKeysP style:<br />
-- skipped<br />
, ("M-<F12>", windows $ W.greedyView "12")<br />
, ("M-S-<F1>", windows $ W.shift "1")<br />
-- etc<br />
</haskell><br />
<br />
== Navigating and Displaying Workspaces ==<br />
=== Using Next Previous Recent Workspaces rather than mod-n ===<br />
The Actions.Plane, Actions.CycleWS, and Actions.CycleRecentWS<br />
extensions allow many ways to navigate workspaces, or shift <br />
windows to other workspaces. <br />
<br />
Plane is easier to set up, especially if you use Gnome. CycleWS<br />
allows binding to nearly any behavior you'd ever want.<br />
Actions.CycleRecentWS allows swapping with previous or next most<br />
recently viewed workspace similar to how many window managers <br />
cycle windows with alt tab.<br />
<br />
In [http://www.n-sch.de/hdocs/xmonad-contrib darcs xmonad-contrib] (will release as 0.9): Layout.IndependentScreens<br />
simulates dwm style workspaces per screen. For spatial navigation more <br />
general than Plane, i.e. four 3x3 grids of workspaces, see <br />
Actions.WorkspaceCursors.<br />
<br />
=== Skipping the Scratchpad workspace while using CycleWS ===<br />
The Util.Scratchpad module provides a configurable floating terminal that is easily shifted to the current workspace or banished to its own "SP" workspace. Most people want the "SP" tag ignored during workspace navigation. (Note that in xmonad newer than 0.8.*<br />
the scratchpad workspace has been renamed to "NSP".)<br />
<br />
Here's one way to do that with Actions.CycleWS, ready to be customized, for example to use HiddenEmptyWSs instead of HiddenNonEmptyWSs, etc.<br />
<br />
Note that <hask>notSP</hask> is defined in the where clause of this example. It is<br />
just another name for <hask>(return $ ("SP" /=) . W.tag) :: X (WindowSpace -> Bool)</hask><br />
Likewise, for <hask>getSortByIndexNoSP</hask>, look in where clause.<br />
<br />
<haskell><br />
--<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig -- optional, but helpful<br />
import Xmonad.Actions.CycleWS<br />
import XMonad.Util.Scratchpad<br />
import XMonad.Util.WorkspaceCompare<br />
<br />
modKey = mod4Mask<br />
<br />
-- other keybindings [ ]<br />
++<br />
-- focus /any/ workspace except scratchpad, even visible<br />
[ ((modKey, xK_Right ), moveTo Next (WSIs notSP))<br />
, ((modKey, xK_Left ), moveTo Prev (WSIs notSP))<br />
<br />
-- move window to /any/ workspace except scratchpad<br />
, ((modKey .|. shiftMask, xK_Right ), shiftTo Next (WSIs notSP))<br />
, ((modKey .|. shiftMask, xK_Left ), shiftTo Prev (WSIs notSP))<br />
<br />
-- focus HiddenNonEmpty wss except scratchpad<br />
, ((modKey .|. controlMask , xK_Right),<br />
windows . W.greedyView =<< findWorkspace getSortByIndexNoSP Next HiddenNonEmptyWS 1)<br />
, ((modKey .|. controlMask , xK_Left),<br />
windows . W.greedyView =<< findWorkspace getSortByIndexNoSP Prev HiddenNonEmptyWS 1)<br />
<br />
-- move window to HiddenNonEmpty wss except scratchpad <br />
, ((modKey .|. shiftMask, xK_Right),<br />
windows . W.shift =<< findWorkspace getSortByIndexNoSP Next HiddenNonEmptyWS 1)<br />
, ((modKey .|. shiftMask, xK_Left),<br />
windows . W.shift =<< findWorkspace getSortByIndexNoSP Prev HiddenNonEmptyWS 1)<br />
<br />
-- move window to and focus HiddenNonEmpty wss except scratchpad<br />
, ((modKey .|. controlMask .|. shiftMask, xK_Right), shiftAndView' Next)<br />
, ((modKey .|. controlMask .|. shiftMask, xK_Left), shiftAndView' Prev)<br />
<br />
-- toggle to the workspace displayed previously, except scratchpad**<br />
, ((modKey, xK_slash myToggle)<br />
]<br />
<br />
-- Make sure to put any where clause after your last list of key bindings*<br />
where notSP = (return $ ("SP" /=) . W.tag) :: X (WindowSpace -> Bool)<br />
-- | any workspace but scratchpad<br />
shiftAndView dir = findWorkspace getSortByIndex dir (WSIs notSP) 1<br />
>>= \t -> (windows . W.shift $ t) >> (windows . W.greedyView $ t)<br />
-- | hidden, non-empty workspaces less scratchpad<br />
shiftAndView' dir = findWorkspace getSortByIndexNoSP dir HiddenNonEmptyWS 1<br />
>>= \t -> (windows . W.shift $ t) >> (windows . W.greedyView $ t)<br />
getSortByIndexNoSP =<br />
fmap (.scratchpadFilterOutWorkspace) getSortByIndex<br />
-- | toggle any workspace but scratchpad<br />
myToggle = windows $ W.view =<< W.tag . head . filter <br />
((\x -> x /= "NSP" && x /= "SP") . W.tag) . W.hidden<br />
<br />
<br />
-- *For example, you could not (++) another list here<br />
<br />
-- ------------------------------------------------------------------------<br />
-- If notSP or some variant of the shiftAndView functions isn't needed, but<br />
-- you do want to use shiftTo or moveTo, delete notSP and use a version of:<br />
-- ((modKey, xK_Right ), moveTo Next . WSIs . return $ ("SP" /=) . W.tag)<br />
</haskell><br />
Also of course, the where definitions, or X () actions bound here can be moved out to<br />
top level definitions if you want to use them repeatedly.<br />
<br />
<nowiki>**</nowiki>This is another way to toggle workspaces except scratchpad.<br />
<br />
<haskell><br />
--<br />
import Control.Monad<br />
<br />
-- toggle to the workspace displayed previously, except scratchpad<br />
, ((modKey, xK_slash toggleSkip ["NSP"])<br />
<br />
-- | toggle any workspace but scratchpad<br />
toggleSkip :: [WorkspaceId] -> X ()<br />
toggleSkip skips = do<br />
hs <- gets (flip skipTags skips . W.hidden . windowset)<br />
unless (null hs) (windows . W.view . W.tag $ head hs)<br />
--<br />
</haskell><br />
<br />
===Do not show scratchpad workspace in status bar or dynamicLog===<br />
You can also use <hask>fmap (.scratchpadFilterOutWorkspace)</hask> on a ppSort<br />
in your logHook.<br />
<haskell><br />
, logHook = dynamicLogWithPP defaultPP {<br />
ppSort = fmap (.scratchpadFilterOutWorkspace) $ ppSort defaultPP<br />
</haskell><br />
or<br />
<haskell><br />
import XMonad.Util.WorkspaceCompare<br />
<br />
-- etc<br />
, logHook = dynamicLogWithPP defaultPP {<br />
ppSort = fmap (.scratchpadFilterOutWorkspace) getSortByTag<br />
--<br />
</haskell><br />
<br />
=== Doing things on another workspace while focus stays on current ===<br />
With darcs xmonad (will release as 0.9) -- see also<br />
[http://code.haskell.org/XMonadContrib/XMonad/Actions/OnScreen.hs Actions.OnScreen] and <code>onScr</code> below.<br />
<br />
You can use something like the following in your keybindings for a two<br />
monitor setup (or two screens via LayoutScreens.) <br />
<haskell><br />
import qualified XMonad.StackSet as W<br />
<br />
-- c here is your XConfig l, aka defaultConfig { ....<br />
, ((modMask c, xK_v), withOtherOf2 W.view) -- focus other visible screen<br />
, ((modMask c, xK_g), withOtherOf2 W.greedyView) -- swap workspaces on screens<br />
, ((modMask c, xK_f), withOtherOf2 W.shift) -- move current window to other screen<br />
, ((modMask c, xK_u), onOtherOf2 W.focusUp) -- focus up on other screen<br />
]<br />
<br />
withOtherOf2 :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()<br />
withOtherOf2 fn = do<br />
tag <- join . gets $ screenWorkspace . (1 -) . W.screen . W.current . windowset<br />
flip whenJust (windows . fn) tag<br />
<br />
onOtherOf2 :: (WindowSet -> WindowSet) -> X ()<br />
onOtherOf2 fn' = do<br />
wset <- gets windowset<br />
other <- screenWorkspace . (1 -) . W.screen . W.current $ wset<br />
windows $ W.view (W.currentTag wset) . fn' . maybe id W.view other<br />
</haskell><br />
<br />
More generally<br />
<haskell><br />
onWorkspace :: WorkspaceId -> (WindowSet -> WindowSet)<br />
-> (WindowSet -> WindowSet)<br />
onWorkspace wsid f w = W.view (W.currentTag w) . f . W.view wsid $ w<br />
<br />
-- silly usage example: focus master on workspace "3"<br />
, ((modMask c, xK_F12), windows $ onWorkspace "3" W.focusMaster)<br />
</haskell><br />
<br />
==== Quick and dirty OnScreen helper ====<br />
With darcs xmonad (will release as 0.9) see also<br />
[http://code.haskell.org/XMonadContrib/XMonad/Actions/OnScreen.hs Actions.OnScreen]<br />
<br />
<haskell><br />
-- For example, to focus a specific workspace on the second screen<br />
-- use something like this in startupHook or a key binding:<br />
-- If the requested screen doesn't exist, the action is done on the<br />
-- current screen instead.<br />
<br />
import qualified XMonad.StackSet as W<br />
-- skipped<br />
, startupHook = onScr 1 W.greedyView "web" <br />
-- skipped<br />
<br />
onScr :: ScreenId -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()<br />
onScr n f i = screenWorkspace n >>= \sn -> windows (f i . maybe id W.view sn)<br />
</haskell><br />
<br />
== Arranging Windows aka Layouts ==<br />
=== Binding keys to a specific layout ===<br />
<br />
Sometimes people want to bind a key to a particular layout, rather<br />
than having to cycle through the available layouts:<br />
<br />
You can do this using the JumpToLayout message from the<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutCombinators.html XMonad.Layout.LayoutCombinators] extension module. For example:<br />
<br />
<haskell><br />
import XMonad hiding ( (|||) ) -- don't use the normal ||| operator<br />
import XMonad.Layout.LayoutCombinators -- use the one from LayoutCombinators instead<br />
import XMonad.Util.EZConfig -- add keybindings easily<br />
<br />
main = xmonad myConfig<br />
<br />
myConfig = defaultConfig {<br />
-- <br />
layoutHook = tall ||| Mirror tall ||| Full<br />
-- <br />
} `additionalKeysP`<br />
[ ("M-<F1>", sendMessage $ JumpToLayout "Tall")<br />
, ("M-<F2>", sendMessage $ JumpToLayout "Mirror Tall")<br />
, ("M-<F3>", sendMessage $ JumpToLayout "Full") <br />
] <br />
<br />
tall = Tall 1 (3/100) (1/2)<br />
</haskell><br />
<br />
=== Docks, Monitors, Sticky Windows ===<br />
See [[#Ignoring a client (or having it sticky)]]<br />
<br />
== Misc ==<br />
=== Using local state in the config file ===<br />
<br />
[[Xmonad/Mutable state in contrib modules or xmonad.hs]]<br />
<br />
=== Sharing a configuration across different hosts ===<br />
<br />
It is possible to have different parts of the configuration file vary from one host to another, without needing a different config file for each host. Here is an example from my configuration file:<br />
<haskell><br />
import System.Posix.Unistd<br />
<br />
-- etc<br />
<br />
main = do<br />
host <- fmap nodeName getSystemID<br />
-- or -- host <- nodeName `fmap` getSystemID<br />
-- or -- host <- nodeName <$> getSystemID -- import Control.Applicative<br />
xmonad $ defaultConfig<br />
{ terminal = "rxvt"<br />
, modMask = (if host === "janice" then<br />
mod1Mask .|. controlMask<br />
else<br />
mod4Mask)<br />
-- also can pass hostname to functions outside main if needed<br />
, logHook = dynamicLogWithPP $ myPP host<br />
, startupHook = whereAmI host<br />
} where -- like this:<br />
whereAmI name = spawn $ xmessage "Silly, this host is " ++ name<br />
<br />
-- and this:<br />
myPP hostname =<br />
if hostname === "janice" then dzenPP else xmobarPP<br />
</haskell><br />
<br />
=== Multi head with VMs VNC or other non standard X ===<br />
To manually split your screen if your X server doesn't deal with xinerama correctly, see the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutScreens.html LayoutScreens extension] or [http://ktown.kde.org/~seli/fakexinerama Fake Xinerama].<br />
<br />
Also, if you're not sure if xmonad was compiled with xinerama support, see the xinerama sections in the [[Xmonad/Frequently_asked_questions|XMonad FAQ]] to check and remedy.</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=IRC_channel&diff=60689
IRC channel
2016-04-20T16:58:50Z
<p>CaleGibbard: </p>
<hr />
<div>Internet Relay Chat is a worldwide text chat service with many thousands<br />
of users among various irc networks.<br />
<br />
The Freenode IRC network hosts the very large #haskell channel, and we've had<br />
up to 1046<br />
concurrent users, making the channel consistently<br />
[http://irc.netsplit.de/channels/details.php?room=%23haskell&net=freenode one of the most popular]<br />
of the thousands of channels on freenode. One famous<br />
resident is [[Lambdabot]], another is [http://hpaste.org hpaste] (see<br />
the [[#Bots|Bots]] section below).<br />
<br />
The IRC channel can be an excellent place to learn more about Haskell,<br />
and to just keep in the loop on new things in the Haskell world. Many<br />
new developments in the Haskell world first appear on the irc channel.<br />
<br />
Since 2009, the Haskell channel has grown large enough that we've split it in two parts:<br />
<br />
* #haskell, for all the usual things<br />
* #haskell-in-depth , for those seeking in depth, or more theoretical discussion<br />
<br />
As always, #haskell remains the primary place for new user questions.<br />
<br />
{| border="0" align="right"<br />
|+ '''#haskell visualized'''<br />
|-<br />
| [[Image:Haskell-current.png|thumb|The social graph, Jan 2008]]<br />
| [[Image:Irc-raw.png|thumb|Daily traffic since 2004]]<br />
|-<br />
| [[Image:Nick-activity.png|thumb|Growth]]<br />
| [[Image:Haskell-wordle-irc.png|thumb|Noun map]]<br />
|}<br />
<br />
== Getting there ==<br />
<br />
If you point your irc client to [irc://chat.freenode.net/haskell chat.freenode.net] and then join the #haskell channel, you'll be there. Alternately, you can try http://java.freenode.net/ or http://webchat.freenode.net/ which connects inside the browser.<br />
<br />
Example, using [http://www.irssi.org/ irssi]:<br />
<br />
$ irssi -c chat.freenode.net -n myname -w mypassword<br />
/join #haskell<br />
<br />
Tip, if you're using Emacs to edit your Haskell sources then why not use it to chat about Haskell? Check out [http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient ERC], The Emacs IRC client. Invoke it like this and follow the commands:<br />
<br />
M-x erc-select<br />
...<br />
/join #haskell<br />
<br />
[[Image:Irc--haskell-screenshot.png|frame|A screenshot of an irssi session in #haskell]]<br />
<br />
== Principles ==<br />
<br />
The #haskell channel is a very friendly, welcoming place to hang out,<br />
teach and learn. The goal of #haskell is to encourage learning and<br />
discussion of Haskell, functional programming, and programming in<br />
general. As part of this we welcome newbies, and encourage teaching of<br />
the language.<br />
<br />
Part of the #haskell success comes from the fact that the community<br />
is quite tight knit &mdash; we know each other &mdash; it's not just a homework<br />
channel. As a result, many collaborative projects have arisen between<br />
Haskell irc channel citizens.<br />
<br />
To maintain the friendly, open culture, the following is required:<br />
<br />
* Low to zero tolerance for ridiculing questions. Insulting new users is unacceptable. New Haskell users should feel entirely comfortable asking questions.<br />
<br />
* Helpful answers should be encouraged with <code>name++</code> karma points, in public, as a reward for providing a good answer.<br />
<br />
* Avoid getting frustrated by negative comments and ambiguous questions. Approach them by asking for details (i.e. [http://en.wikipedia.org/wiki/Socratic_method Socratic questioning]), rather than challenging the competence of the writer (ad hominem). As the channel grows, we see a diverse range of people with different programming backgrounds getting accustomed to Haskell. Be patient and take satisfaction from spreading knowledge.<br />
<br />
== History ==<br />
<br />
The #haskell channel appeared in the late 90s, and really got going<br />
in early 2001, with the help of Shae Erisson (aka shapr).<br />
<br />
== Related channels ==<br />
<br />
In addition to the main Haskell channel there are also:<br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Channel<br />
! Purpose<br />
|-<br />
| #haskell-br<br />
| Brazilian Portuguese (pt_BR) speakers<br />
|-<br />
| #haskell.cz<br />
| Czech speakers (UTF-8)<br />
|- <br />
| #haskell.de<br />
| German speakers<br />
|-<br />
| #haskell.dut<br />
| Dutch speakers<br />
|-<br />
| #haskell.es<br />
| Spanish speakers<br />
|-<br />
| #haskell.fi<br />
| Finnish speakers<br />
|-<br />
| #haskell-fr (note the hyphen!)<br />
| French speakers <br />
|-<br />
| #haskell.hr<br />
| Croatian speakers<br />
|-<br />
| #haskell-id (note the hyphen!)<br />
| Indonesian speakers <br />
|-<br />
| #haskell.it <br />
| Italian speakers<br />
|-<br />
| #haskell.jp <br />
| Japanese speakers<br />
|-<br />
| #haskell.kr<br />
| Korean speakers<br />
|-<br />
| #haskell.no <br />
| Norwegian speakers<br />
|-<br />
| #haskell.pt<br />
| Portuguese speakers<br />
|-<br />
| #haskell-pl<br />
| Polish speakers<br />
|-<br />
| #haskell.ru <br />
| Russian speakers. Seems that most of them migrated to Jabber conference (haskell@conference.jabber.ru).<br />
|-<br />
| #haskell_ru <br />
| Russian speakers again, in UTF-8. For those, who prefer good ol' IRC channel with a lambdabot.<br />
|-<br />
| #haskell-ro<br />
| Romanian speakers.<br />
|-<br />
| #haskell.se <br />
| Swedish speakers<br />
|-<br />
| #haskell.tw<br />
| Chinese speakers (mainly in Taiwan)<br />
|-<br />
| #haskell.vn<br />
| Vietnamese speakers<br />
|-<br />
| #haskell-beginners<br />
| Haskell people focused on teaching and learning Haskell, not just beginners.<br />
|-<br />
| #haskell-offtopic<br />
| Haskell people talking about anything except Haskell itself (no TLS required)<br />
|-<br />
| #haskell-blah <br />
| Haskell people talking about anything except Haskell itself (TLS required)<br />
|-<br />
| #haskell-game<br />
| The hub for Haskell-based [[Game Development|game development]]<br />
|-<br />
| #haskell-in-depth<br />
| slower paced discussion of use, theory, implementation etc with no monad tutorials!<br />
|-<br />
| #haskell-iphone<br />
| Haskell-based [[iPhone]] development<br />
|-<br />
| #haskell-apple<br />
| projects that target iOS or OS X using Haskell. <br />
|-<br />
| #haskell-lisp<br />
| [[Haskell Lisp]] - projects that are creating Lisps written in Haskell, or Haskell implementations written in Lisps. <br />
|-<br />
| #haskell-llvm<br />
| For projects using Haskell and LLVM<br />
|-<br />
| #haskell-overflow<br />
| Overflow conversations<br />
|-<br />
| #haskell-web<br />
| Friendly, practical discussion of haskell web app/framework/server development<br />
|-<br />
| #haskell-robotics<br />
| Discussion about the use of Haskell for robotics applications.<br />
|-<br />
| '''Platform-specific:'''<br />
|<br />
|-<br />
| #arch-haskell <br />
| [[Arch Linux]]/ specific Haskell conversations<br />
|-<br />
| #fedora-haskell<br />
| [[Fedora]] Haskell SIG<br />
|-<br />
| #gentoo-haskell <br />
| [[Gentoo]]/Linux specific Haskell conversations<br />
|-<br />
| '''Projects using haskell:'''<br />
|<br />
|-<br />
| #darcs <br />
| [[Darcs]] revision control system<br />
|-<br />
| #diagrams<br />
| [[Diagrams]] EDSL<br />
|-<br />
| #hackage<br />
| Haskell's software distribution infrastructure<br />
|-<br />
| #haskell-lens<br />
| [[Lens]] discussions<br />
|-<br />
| #happs<br />
| [http://happstack.com Happstack] web framework<br />
|-<br />
| #hledger<br />
| [http://hledger.org hledger] accounting tools and library<br />
|-<br />
| #leksah<br />
| [http://leksah.org Leksah] IDE for Haskell development<br />
|-<br />
| #perl6 <br />
| [http://www.pugscode.org Perl 6] development (plenty of Haskell chat there too)<br />
|-<br />
| #snowdrift <br />
| [https://snowdrift.coop Snowdrift.coop] Yesod-based web platform for funding free/libre/open works, welcomes Haskell volunteer devs including beginners<br />
|-<br />
| #snapframework<br />
| [http://snapframework.com/ Snap] web framework<br />
|-<br />
| #xmonad<br />
| [http://xmonad.org Xmonad] tiling window manager<br />
|-<br />
| #yesod<br />
| [http://yesodweb.com Yesod] web framework<br />
|-<br />
| #chicagohaskell<br />
| [http://chicagohaskell.com Chicago Haskell] programmers group<br />
|}<br />
<br />
== Logs ==<br />
<br />
'''Logs''' are kept at http://tunes.org/~nef/logs/haskell/ and can be searched at http://ircbrowse.net/browse/haskell<br />
<br />
<!-- anywhere else? ircbrowse.com is a goner, apparently --><br />
<br />
== Bots ==<br />
<br />
There are various bots on the channel. Their names and usage are described here.<br />
<br />
=== lambdabot ===<br />
<br />
[[Lambdabot]] is both the name of a software package and a bot on the channel. It provides many useful services for visitors to the IRC channel. It is available as a haskell package and can be integrated into ghci. Details on the software are found on a [[Lambdabot|separate wiki page]].<br />
<br />
Here is its interface for the IRC user:<br />
<br />
lambdabot's commands are prepended by a '@' sign.<br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Command<br />
! Usage<br />
|-<br />
| @help<br />
| display help to other commands, but help text is not available for all commands.<br />
|-<br />
| @type EXPR or ':t' EXPR<br />
| shows the type of an expression<br />
|-<br />
| @kind TYPECONSTRUCTOR<br />
| shows the kind of a type constructor<br />
|-<br />
| @run EXPR or '>' EXPR<br />
| evaluates EXPR<br />
|-<br />
| @pl FUNCTION<br />
| shows a [[pointfree]] version of FUNCTION<br />
|-<br />
| @pointful FUNCTION or '@unpl' FUNCTION<br />
| shows a 'pointful' version of FUNCTION<br />
|-<br />
| @tell <nick> <msg> -- same as @ask<br />
| Next time <nick> speaks in channel they will be notified they have a message pending and how to receive it.<br />
|}<br />
<br />
=== preflex ===<br />
<br />
is the name of a lambdabot with more commands/plugins enabled. It is run by ?? To talk to preflex, write <tt>preflex: command ARGS</tt><br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Command<br />
! Usage<br />
|-<br />
| help COMMAND<br />
| displays help to other commands.<br />
|-<br />
| list<br />
| lists all plugins with their commands<br />
|-<br />
| NICK++ / NICK--<br />
| in/decrements the karma of NICK.<br />
|-<br />
| karma NICK<br />
| shows the karma of NICK<br />
|-<br />
| seen NICK<br />
| shows information about the last message of a user<br />
|-<br />
| tell / ask<br />
| sends NICK MSG a message when she becomes active.<br />
|-<br />
| xseen<br />
| ''see 'seen' ?? any difference ?''<br />
|-<br />
| quote NICK<br />
| prints a random quote of NICK<br />
|-<br />
| remember NAME QUOTE<br />
| associates NAME with quote. can be accessed by 'quote'<br />
|-<br />
| ...<br />
| ...<br />
|}<br />
<br />
=== hpaste ===<br />
The hpaste bot provides a notification interface to the [http://hpaste.org hpaste pastebin]. [[Hpaste.el|Emacs integration]] is available.<br />
<br />
''Usage?''<br />
<br />
''Not online often !? ''<br />
<br />
=== hackage ===<br />
The hackage bot provides real-time notifications of new package uploads to [http://hackage.haskell.org Hackage].<br />
<br />
== Locations ==<br />
<br />
To get an overview of where everybody on the channel might<br />
be, physically, please visit [[Haskell user locations]].<br />
<br />
<br />
[[Category:Community]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Avoiding_partial_functions&diff=60652
Avoiding partial functions
2016-03-22T16:17:48Z
<p>CaleGibbard: </p>
<hr />
<div>There are several [[partial functions]] in the Haskell standard library.<br />
If you use them, you always risk to end up with an undefined.<br />
In this article we give some hints how to avoid them, leading to code that you can be more confident about.<br />
<br />
For a partial function f the general pattern is:<br />
Wherever we write "check whether x is in the domain of f before computing f x",<br />
we replace it by combination of check and computation of f.<br />
<br />
== fromJust ==<br />
<br />
You should replace<br />
<haskell><br />
if isNothing mx<br />
then g<br />
else h (fromJust mx)<br />
</haskell><br />
by<br />
<haskell><br />
case mx of<br />
Nothing -> g<br />
Just x -> h x<br />
</haskell><br />
which is equivalent to<br />
<haskell><br />
maybe g h mx<br />
</haskell><br />
<br />
== head, tail ==<br />
<br />
You should replace<br />
<haskell><br />
if null xs<br />
then g<br />
else h (head xs) (tail xs)<br />
</haskell><br />
by<br />
<haskell><br />
case xs of<br />
[] -> g<br />
y:ys -> h y ys<br />
</haskell><br />
<br />
== init, last ==<br />
<br />
You may replace<br />
<haskell><br />
if null xs<br />
then g<br />
else h (init xs) (last xs)<br />
</haskell><br />
by<br />
<haskell><br />
case xs of<br />
[] -> g<br />
y:ys -> uncurry h $ viewRTotal y ys<br />
<br />
viewRTotal :: a -> [a] -> ([a], a)<br />
viewRTotal x xs =<br />
forcePair $<br />
foldr<br />
(\x0 go y -> case go y of ~(zs,z) -> (x0:zs,z))<br />
(\y -> ([],y))<br />
xs x<br />
<br />
forcePair :: (a,b) -> (a,b)<br />
forcePair ~(a,b) = (a,b)<br />
</haskell><br />
<br />
Alternatively, you may import from {{HackagePackage|id=utility-ht}}:<br />
* [http://hackage.haskell.org/packages/archive/utility-ht/0.0.8/doc/html/Data-Tuple-HT.html forcePair]<br />
* [http://hackage.haskell.org/packages/archive/utility-ht/0.0.8/doc/html/Data-List-HT.html viewR]<br />
* [http://hackage.haskell.org/packages/archive/utility-ht/0.0.8/doc/html/Data-List-HT.html switchR].<br />
<br />
== (!!) ==<br />
<br />
You should replace<br />
<haskell><br />
if k < length xs<br />
then xs!!k<br />
else y<br />
</haskell><br />
by<br />
<haskell><br />
case drop k xs of<br />
x:_ -> x<br />
[] -> y<br />
</haskell><br />
<br />
This is also more lazy, since for computation of <hask>length</hask> you have to visit every element of the list.<br />
<br />
<br />
== irrefutable pattern match on (:) ==<br />
<br />
You should replace<br />
<haskell><br />
if k < length xs<br />
then let (prefix,x:suffix) = splitAt k xs<br />
in g prefix x suffix<br />
else y<br />
</haskell><br />
by<br />
<haskell><br />
case splitAt k xs of<br />
(prefix,x:suffix) -> g prefix x suffix<br />
(_,[]) -> y<br />
</haskell><br />
<br />
<br />
== minimum ==<br />
<br />
The function <hask>isLowerLimit</hask> checks if a number is a lower limit to a sequence.<br />
You may implement it with the partial function <hask>minimum</hask>.<br />
<haskell><br />
isLowerLimit :: Ord a => a -> [a] -> Bool<br />
isLowerLimit x ys = x <= minimum ys<br />
</haskell><br />
It fails if <hask>ys</hask> is empty or infinite.<br />
<br />
You should replace it by<br />
<haskell><br />
isLowerLimit x = all (x<=)<br />
</haskell><br />
This definition terminates for infinite lists, if <hask>x</hask> is not a lower limit. It aborts immediately if an element is found which is below <hask>x</hask>.<br />
Thus it is also faster for finite lists.<br />
Even more: It also works for empty lists.<br />
<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Style]]<br />
[[Category:Idioms]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Roll_your_own_IRC_bot/Source&diff=59857
Roll your own IRC bot/Source
2015-06-17T00:57:52Z
<p>CaleGibbard: Replaced content with "This page once contained a complete copy of the source code for the bot described in Roll your own IRC bot, but it fell out of date with the article (and became uncomp..."</p>
<hr />
<div>This page once contained a complete copy of the source code for the bot described in [[Roll your own IRC bot]], but it fell out of date with the article (and became uncompilable). That page already has source for the bot anyway, so there's not much point in keeping this separate one.</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Roll_your_own_IRC_bot&diff=59856
Roll your own IRC bot
2015-06-17T00:53:10Z
<p>CaleGibbard: Remove link to outdated version of the source which is unnecessary since the complete source is available in a single snippet on this page anyhow.</p>
<hr />
<div><br />
This tutorial is designed as a practical guide to writing real world<br />
code in [http://haskell.org Haskell] and hopes to intuitively motivate<br />
and introduce some of the advanced features of Haskell to the novice<br />
programmer. Our goal is to write a concise, robust and elegant<br />
[http://haskell.org/haskellwiki/IRC_channel IRC] bot in Haskell.<br />
<br />
== Getting started ==<br />
<br />
You'll need a reasonably recent version of [http://haskell.org/ghc GHC]<br />
or [http://haskell.org/hugs Hugs]. Our first step is to get on the<br />
network. So let's start by importing the Network package, and the<br />
standard IO library and defining a server to connect to.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
t <- hGetContents h<br />
print t<br />
</haskell><br />
<br />
The key here is the <code>main</code> function. This is the entry point to a Haskell program. We first connect to the server, then set the buffering on the socket off. Once we've got a socket, we can then just read and print any data we receive.<br />
<br />
Put this code in the module <code>1.hs</code> and we can then run it. Use whichever system you like:<br />
<br />
Using runhaskell:<br />
<br />
$ runhaskell 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or we can just compile it to an executable with GHC:<br />
<br />
$ ghc --make 1.hs -o tutbot<br />
Chasing modules from: 1.hs<br />
Compiling Main ( 1.hs, 1.o )<br />
Linking ...<br />
$ ./tutbot<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or using GHCi:<br />
<br />
$ ghci 1.hs<br />
*Main> main<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or in Hugs:<br />
<br />
$ runhugs 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Great! We're on the network.<br />
<br />
== Talking IRC ==<br />
<br />
Now we're listening to the server, we better start sending some information back. Three details are important: the nick, the user name, and a channel to join. So let's send those.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
import Text.Printf<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
write h "NICK" nick<br />
write h "USER" (nick++" 0 * :tutorial bot")<br />
write h "JOIN" chan<br />
listen h<br />
<br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
<br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
Now, we've done quite a few things here. Firstly, we import <code>Text.Printf</code>, which will be useful. We also set up a channel name and bot nickname. The <code>main</code> function has been extended to send messages back to the IRC server using a <code>write</code> function. Let's look at that a bit more closely:<br />
<br />
<haskell><br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
</haskell><br />
<br />
We've given <code>write</code> an explicit type to help document it, and we'll use explicit types signatures from now on, as they're just good practice (though of course not required, as Haskell uses type inference to work out the types anyway).<br />
<br />
The <code>write</code> function takes 3 arguments; a handle (our socket), and then two strings representing an IRC protocol action, and any arguments it takes. <code>write</code> then uses <code>hPrintf</code> to build an IRC message and write it over the wire to the server. For debugging purposes we also print to standard output the message we send.<br />
<br />
Our second function, <code>listen</code>, is as follows:<br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
This function takes a Handle argument, and sits in an infinite loop reading lines of text from the network and printing them. We take advantage of two powerful features; lazy evaluation and higher order functions to roll our own loop control structure, <code>forever</code>, as a normal function! <code>forever</code> takes a chunk of code as an argument, evaluates it and recurses - an infinite loop function. It is very common to roll our own control structures in Haskell this way, using higher order functions. No need to add new syntax to the language, lisp-like macros or meta programming - you just write a normal function to implement whatever control flow you wish. We can also avoid <code>do</code>-notation, and directly write: <code>forever a = a >> forever a</code>.<br />
<br />
Let's run this thing:<br />
<br />
<haskell><br />
$ runhaskell 2.hs<br />
> NICK tutbot<br />
> USER tutbot 0 * :tutorial bot<br />
> JOIN #tutbot-testing<br />
NOTICE AUTH :*** Looking up your hostname...<br />
NOTICE AUTH :*** Found your hostname, welcome back<br />
NOTICE AUTH :*** Checking ident<br />
NOTICE AUTH :*** No identd (auth) response<br />
:orwell.freenode.net 001 tutbot :Welcome to the freenode IRC Network tutbot<br />
:orwell.freenode.net 002 tutbot :Your host is orwell.freenode.net<br />
...<br />
:tutbot!n=tutbot@aa.bb.cc.dd JOIN :#tutbot-testing<br />
:orwell.freenode.net MODE #tutbot-testing +ns<br />
:orwell.freenode.net 353 tutbot @ #tutbot-testing :@tutbot<br />
:orwell.freenode.net 366 tutbot #tutbot-testing :End of /NAMES list.<br />
</haskell><br />
<br />
And we're in business! From an IRC client, we can watch the bot connect:<br />
<br />
15:02 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:02 dons> hello<br />
<br />
And the bot logs to standard output:<br />
<br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :hello<br />
<br />
We can now implement some commands.<br />
<br />
== A simple interpreter ==<br />
<br />
Add these additional imports before changing the <code>listen</code> function.<br />
<br />
<haskell><br />
import Data.List<br />
import System.Exit<br />
</haskell><br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
t <- hGetLine h<br />
let s = init t<br />
if ping s then pong s else eval h (clean s)<br />
putStrLn s<br />
where<br />
forever a = a >> forever a<br />
<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write h "PONG" (':' : drop 6 x)<br />
</haskell><br />
<br />
We add 3 features to the bot here by modifying <code>listen</code>.<br />
Firstly, it responds to <code>PING</code> messages: <code>if ping s then pong s ... </code>.<br />
This is useful for servers that require pings to keep clients connected.<br />
Before we can process a command, remember the IRC protocol generates<br />
input lines of the form:<br />
<br />
<haskell><br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :!id foo<br />
</haskell><br />
<br />
so we need a <code>clean</code> function to simply drop the leading ':' character, and then everything up to the next ':', leaving just the actual command content. We then pass this cleaned up string to <code>eval</code>, which then dispatches bot commands.<br />
<br />
<haskell><br />
eval :: Handle -> String -> IO ()<br />
eval h "!quit" = write h "QUIT" ":Exiting" >> exitWith ExitSuccess<br />
eval h x | "!id " `isPrefixOf` x = privmsg h (drop 4 x)<br />
eval _ _ = return () -- ignore everything else<br />
</haskell><br />
<br />
So, if the single string "!quit" is received, we inform the server and exit the program. If a string beginning with "!id" appears, we echo any argument string back to the server (<code>id</code> is the Haskell identity function, which just returns its argument). Finally, if no other matches occur, we do nothing.<br />
<br />
We add the <code>privmsg</code> function - a useful wrapper over <code>write</code> for sending <code>PRIVMSG</code> lines to the server.<br />
<br />
<haskell><br />
privmsg :: Handle -> String -> IO ()<br />
privmsg h s = write h "PRIVMSG" (chan ++ " :" ++ s)<br />
</haskell><br />
<br />
Here's a transcript from our minimal bot running in channel:<br />
<br />
15:12 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:13 dons> !id hello, world!<br />
15:13 tutbot> hello, world!<br />
15:13 dons> !id very pleased to meet you.<br />
15:13 tutbot> very pleased to meet you.<br />
15:13 dons> !quit<br />
15:13 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
Now, before we go further, let's refactor the code a bit.<br />
<br />
== Roll your own monad ==<br />
<br />
A small annoyance so far has been that we've had to thread around our socket to every function that needs to talk to the network. The socket is essentially <em>immutable state</em>, that could be treated as a global read only value in other languages. In Haskell, we can implement such a structure using a state <em>monad</em>. Monads are a very powerful abstraction, and we'll only touch on them here. The interested reader is referred to [http://www.haskell.org/haskellwiki/All_About_Monads All About Monads]. We'll be using a custom monad specifically to implement a read-only global state for our bot.<br />
<br />
The key requirement is that we wish to be able to perform IO actions, as well as thread a small state value transparently through the program. As this is Haskell, we can take the extra step of partitioning our stateful code from all other program code, using a new type.<br />
<br />
So let's define a small state monad:<br />
<haskell><br />
data Bot = Bot { socket :: Handle }<br />
<br />
type Net = ReaderT Bot IO<br />
</haskell><br />
<br />
Firstly, we define a data type for the global state. In this case, it is the <code>Bot</code> type, a simple struct storing our network socket. We then layer this data type over our existing IO code, with a <em>monad transformer</em>. This isn't as scary as it sounds and the effect is that we can just treat the socket as a global read-only value anywhere we need it. We'll call this new io + state structure the <code>Net</code> monad. <code>ReaderT</code> is a <em>type constructor</em>, essentially a type function, that takes 2 types as arguments, building a result type: the <code>Net</code> monad type.<br />
<br />
We can now throw out all that socket threading and just grab the socket when we need it. The key steps are connecting to the server, followed by the initialisation of our new state monad and then to run the main bot loop with that state. We add a small function, which takes the intial bot state and evaluates the bot's <code>run</code> loop "in" the Net monad, using the Reader monad's <code>runReaderT</code> function:<br />
<br />
<haskell><br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
where <code>run</code> is a small function to register the bot's nick, join a channel, and start listening for commands.<br />
<br />
While we're here, we can tidy up the main function a little by using <code>Control.Exception.bracket</code> to explicitly delimit the connection, shutdown and main loop phases of the program - a useful technique.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
That is, the higher order function <code>bracket</code> takes 3 arguments: a function to connect to the server, a function to disconnect and a main loop to run in between. We can use <code>bracket</code> whenever we wish to run some code before and after a particular action - like <code>forever</code>, this is another control structure implemented as a normal Haskell function.<br />
<br />
Rather than threading the socket around, we can now simply ask for it when needed. Note that the type of <code>write</code> changes - it is in the Net monad, which tells us that the bot must already by connected to a server (and thus it is ok to use the socket, as it is initialised).<br />
<br />
<haskell><br />
--<br />
-- Send a message out to the server we're currently connected to<br />
--<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
</haskell><br />
<br />
In order to use both state and IO, we use the small <code>io</code> function to <em>lift</em> an IO expression into the Net monad making that IO function available to code in the <code>Net</code> monad.<br />
<br />
<haskell><br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Similarly, we can combine IO actions with pure functions by lifting them into the IO monad. We can therefore simplify our <code>hGetLine</code> call:<br />
<haskell><br />
do t <- io (hGetLine h)<br />
let s = init t<br />
</haskell><br />
by lifting <code>init</code> over IO:<br />
<haskell><br />
do s <- init `fmap` io (hGetLine h)<br />
</haskell><br />
<br />
The monadic, stateful, exception-handling bot in all its glory:<br />
<br />
<haskell><br />
import Data.List<br />
import Network<br />
import System.IO<br />
import System.Exit<br />
import Control.Arrow<br />
import Control.Monad.Reader<br />
import Control.Exception<br />
import Text.Printf<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
-- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state.<br />
type Net = ReaderT Bot IO<br />
data Bot = Bot { socket :: Handle }<br />
<br />
-- Set up actions to run on start and end, and run the main loop<br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = runReaderT run st<br />
<br />
-- Connect to the server and return the initial bot state<br />
connect :: IO Bot<br />
connect = notify $ do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h)<br />
where<br />
notify a = bracket_<br />
(printf "Connecting to %s ... " server >> hFlush stdout)<br />
(putStrLn "done.")<br />
a<br />
<br />
-- We're in the Net monad now, so we've connected successfully<br />
-- Join a channel, and start processing commands<br />
run :: Net ()<br />
run = do<br />
write "NICK" nick<br />
write "USER" (nick++" 0 * :tutorial bot")<br />
write "JOIN" chan<br />
asks socket >>= listen<br />
<br />
-- Process each line from the server<br />
listen :: Handle -> Net ()<br />
listen h = forever $ do<br />
s <- init `fmap` io (hGetLine h)<br />
io (putStrLn s)<br />
if ping s then pong s else eval (clean s)<br />
where<br />
forever a = a >> forever a<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write "PONG" (':' : drop 6 x)<br />
<br />
-- Dispatch a command<br />
eval :: String -> Net ()<br />
eval "!quit" = write "QUIT" ":Exiting" >> io (exitWith ExitSuccess)<br />
eval x | "!id " `isPrefixOf` x = privmsg (drop 4 x)<br />
eval _ = return () -- ignore everything else<br />
<br />
-- Send a privmsg to the current chan + server<br />
privmsg :: String -> Net ()<br />
privmsg s = write "PRIVMSG" (chan ++ " :" ++ s)<br />
<br />
-- Send a message out to the server we're currently connected to<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
<br />
-- Convenience.<br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Note that we threw in a new control structure, <code>notify</code>, for fun. Now we're almost done! Let's run this bot. Using runhaskell:<br />
<br />
$ runhaskell 4.hs<br />
<br />
or using GHC:<br />
<br />
$ ghc --make 4.hs -o tutbot<br />
Chasing modules from: 4.hs<br />
Compiling Main ( 4.hs, 4.o )<br />
Linking ...<br />
$ ./tutbot<br />
<br />
If you're using Hugs, you'll have to use the <code>-98</code> flag:<br />
<br />
$ runhugs -98 4.hs<br />
<br />
And from an IRC client we can watch it connect:<br />
<br />
15:26 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:28 dons> !id all good?<br />
15:28 tutbot> all good?<br />
15:28 dons> !quit<br />
15:28 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
So we now have a bot with explicit read-only monadic state, error handling, and some basic IRC operations. If we wished to add read-write state, we need only change the <code>ReaderT</code> transformer to <code>StateT</code>.<br />
<br />
== Extending the bot ==<br />
<br />
Let's implement a basic new command: uptime tracking. Conceptually, we need to remember the time the bot starts. Then, if a user requests, we work out the total running time and print it as a string. A nice way to do this is to extend the bot's state with a start time field:<br />
<br />
<haskell><br />
import System.Time<br />
</haskell><br />
<br />
<haskell><br />
data Bot = Bot { socket :: Handle, starttime :: ClockTime }<br />
</haskell><br />
<br />
We can then modify the initial <code>connect</code> function to also set the start time.<br />
<br />
<haskell><br />
connect :: IO Bot<br />
connect = notify $ do<br />
t <- getClockTime<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h t)<br />
</haskell><br />
<br />
We then add a new case to the <code>eval</code> function, to handle uptime requests:<br />
<br />
<haskell><br />
eval "!uptime" = uptime >>= privmsg<br />
</haskell><br />
<br />
This will just run the <code>uptime</code> function and send it back to the server. <code>uptime</code> itself is:<br />
<br />
<haskell><br />
uptime :: Net String<br />
uptime = do<br />
now <- io getClockTime<br />
zero <- asks starttime<br />
return . pretty $ diffClockTimes now zero<br />
</haskell><br />
<br />
That is, in the Net monad, find the current time and the start time, and then calculate the difference, returning that number as a string. Rather than use the normal representation for dates, we'll write our own custom formatter for dates:<br />
<br />
<haskell><br />
--<br />
-- Pretty print the date in '1d 9h 9m 17s' format<br />
--<br />
pretty :: TimeDiff -> String<br />
pretty td =<br />
unwords $ map (uncurry (++) . first show) $<br />
if null diffs then [(0,"s")] else diffs<br />
where merge (tot,acc) (sec,typ) = let (sec',tot') = divMod tot sec<br />
in (tot',(sec',typ):acc)<br />
metrics = [(86400,"d"),(3600,"h"),(60,"m"),(1,"s")]<br />
diffs = filter ((/= 0) . fst) $ reverse $ snd $<br />
foldl' merge (tdSec td,[]) metrics<br />
</haskell><br />
<br />
And that's it. Running the bot with this new command:<br />
<br />
16:03 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
16:03 dons> !uptime<br />
16:03 tutbot> 51s<br />
16:03 dons> !uptime<br />
16:03 tutbot> 1m 1s<br />
16:12 dons> !uptime<br />
16:12 tutbot> 9m 46s<br />
<br />
== Where to now? ==<br />
<br />
This is just a flavour of application programming in Haskell, and only<br />
hints at the power of Haskell's lazy evaluation, static typing, monadic<br />
effects and higher order functions. There is much, much more to be said<br />
on these topics. Some places to start:<br />
<br />
* A [[/Transcript|full transcript]].<br />
* [[Haskell|Haskell.org]]<br />
* [[Example_code|More Haskell code]]<br />
* [[Books and tutorials|Learning Haskell]]<br />
* A gallery of [[Libraries_and_tools/Network|network apps]] in Haskell<br />
<br />
Or take the bot home and hack! Some suggestions:<br />
* Use <code>forkIO</code> to add a command line interface, and you've got yourself an irc client with 4 more lines of code.<br />
* Port some commands from [[Lambdabot]].<br />
<br />
Author: [http://www.cse.unsw.edu.au/~dons Don Stewart]<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Code]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=All_About_Monads&diff=58098
All About Monads
2014-05-16T00:21:26Z
<p>CaleGibbard: /* A list is also a monad */</p>
<hr />
<div>''All About Monads'' is a tutorial on monads and monad transformers and a walk-through of common monad instances. You can download a PDF version [http://ompldr.org/vY29zdw/All_About_Monads.pdf here] or [http://www.cs.rit.edu/~swm/cs561/All_About_Monads.pdf here]. And [http://web.archive.org/web/20061211101052/http://www.nomaware.com/monads/html/index.html here] is a version of the article which includes [http://web.archive.org/web/20061210172052/http://www.nomaware.com/monads/html/examples.html source code].<br />
<br />
Attempts are being made at porting the tutorial to this wiki; what you're seeing below is a preview of the result of that effort. If you wish to help out you should fork [https://github.com/dag/all-about-monads this GitHub repo] rather than edit this page, for now.<br />
<br />
= Introduction =<br />
<br />
== What is a monad? ==<br />
<br />
A monad is a way to structure computations in terms of values and sequences of computations using those values. Monads allow the programmer to build up computations using sequential building blocks, which can themselves be sequences of computations. The monad determines how combined computations form a new computation and frees the programmer from having to code the combination manually each time it is required.<br />
<br />
''It is useful to think of a monad as a strategy for combining computations into more complex computations.'' For example, you should be familiar with the <code>Maybe</code> type in Haskell:<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
</haskell><br />
which represents the type of computations which may fail to return a result. The <code>Maybe</code> type suggests a strategy for combining computations which return <code>Maybe</code> values: if a combined computation consists of one computation <code>B</code> that depends on the result of another computation <code>A</code>, then the combined computation should yield <code>Nothing</code> whenever either <code>A</code> or <code>B</code> yield <code>Nothing</code> and the combined computation should yield the result of <code>B</code> applied to the result of <code>A</code> when both computations succeed.<br />
<br />
Other monads exist for building computations that perform I/O, have state, may return multiple results, etc. There are as many different type of monads as there are strategies for combining computations, but there are certain monads that are especially useful and are common enough that they are part of the standard [http://www.haskell.org/onlinelibrary/ Haskell 98 libraries]. These monads are each described in [[introII.html|Part II]].<br />
<br />
== Why should I make the effort to understand monads? ==<br />
<br />
The sheer number of different [http://haskell.cs.yale.edu/bookshelf/#monads monad tutorials] on the internet is a good indication of the difficulty many people have understanding the concept. This is due to the abstract nature of monads and to the fact that they are used in several different capacities, which can confuse the picture of exactly what a monad is and what it is good for.<br />
<br />
In Haskell, monads play a central role in the I/O system. It is not essential to understand monads to do I/O in Haskell, but understanding the I/O monad will improve your code and extend your capabilities.<br />
<br />
For the programmer, monads are useful tools for structuring functional programs. They have three properties that make them especially useful:<br />
<br />
# Modularity - They allow computations to be composed from simpler computations and separate the combination strategy from the actual computations being performed.<br />
# Flexibility - They allow functional programs to be much more adaptable than equivalent programs written without monads. This is because the monad distills the computational strategy into a single place instead of requiring it be distributed throughout the entire program.<br />
# Isolation - They can be used to create imperative-style computational structures which remain safely isolated from the main body of the functional program. This is useful for incorporating side-effects (such as I/O) and state (which violates referential transparency) into a pure functional language like Haskell.<br />
<br />
Each of these features will be revisited later in the tutorial in the context of specific monads.<br />
<br />
Meet the Monads<br />
<br />
= Meet the Monads =<br />
<br />
We will use the <code>Maybe</code> type constructor throughout this chapter, so you should familiarize yourself with the definition and usage of [http://www.haskell.org/onlinelibrary/maybe.html <code>Maybe</code>] before continuing.<br />
<br />
== Type constructors ==<br />
<br />
To understand monads in Haskell, you need to be comfortable dealing with type constructors. A ''type constructor'' is a parameterized type definition used with polymorphic types. By supplying a type constructor with one or more concrete types, you can construct a new concrete type in Haskell. In the definition of <code>Maybe</code>:<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
</haskell><br />
<code>Maybe</code> is a type constructor and <code>Nothing</code> and <code>Just</code> are data constructors. You can construct a data value by applying the <code>Just</code> data constructor to a value:<br />
<br />
<haskell><br />
country = Just "China"<br />
</haskell><br />
In the same way, you can construct a type by applying the <code>Maybe</code> type constructor to a type:<br />
<br />
<haskell><br />
lookupAge :: DB -> String -> Maybe Int<br />
</haskell><br />
Polymorphic types are like containers that are capable of holding values of many different types. So <code>Maybe Int</code> can be thought of as a <code>Maybe</code> container holding an <code>Int</code> value (or <code>Nothing</code>) and <code>Maybe String</code> would be a <code>Maybe</code> container holding a <code>String</code> value (or <code>Nothing</code>). In Haskell, we can also make the type of the container polymorphic, so we could write &quot;<code>m a</code>&quot; to represent a container of some type holding a value of some type!<br />
<br />
We often use type variables with type constructors to describe abstract features of a computation. For example, the polymorphic type <code>Maybe a</code> is the type of all computations that may return a value or <code>Nothing</code>. In this way, we can talk about the properties of the container apart from any details of what the container might hold.<br />
<br />
[[Image:info.png]] If you get messages about &quot;kind errors&quot; from the compiler when working with monads, it means that you are not using the type constructors correctly. <br /><br />
<br />
<br />
== Maybe a monad ==<br />
<br />
In Haskell a monad is represented as a type constructor (call it <code>m</code>), a function that builds values of that type (<code>a -> m a</code>), and a function that combines values of that type with computations that produce values of that type to produce a new computation for values of that type (<code>m a -> (a -> m b) -> m b</code>). Note that the container is the same, but the type of the contents of the container can change. It is customary to call the monad type constructor &quot;<code>m</code>&quot; when discussing monads in general. The function that builds values of that type is traditionally called &quot;<code>return</code>&quot; and the third function is known as &quot;bind&quot; but is written &quot;<code>>>=</code>&quot;. The signatures of the functions are:<br />
<br />
<haskell><br />
-- the type of monad m<br />
data m a = ... <br />
<br />
-- return is a type constructor that creates monad instances <br />
return :: a -> m a<br />
<br />
-- bind is a function that combines a monad instance m a with a computation<br />
-- that produces another monad instance m b from a's to produce a new<br />
-- monad instance m b<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
</haskell><br />
Roughly speaking, the monad type constructor defines a type of computation, the <code>return</code> function creates primitive values of that computation type and <code>>>=</code> combines computations of that type together to make more complex computations of that type. Using the container analogy, the type constructor <code>m</code> is a container that can hold different values. <code>m a</code> is a container holding a value of type <code>a</code>. The <code>return</code> function puts a value into a monad container. The <code>>>=</code> function takes the value from a monad container and passes it to a function to produce a monad container containing a new value, possibly of a different type. The <code>>>=</code> function is known as &quot;bind&quot; because it binds the value in a monad container to the first argument of a function. By adding logic to the binding function, a monad can implement a specific strategy for combining computations in the monad.<br />
<br />
This will all become clearer after the example below, but if you feel particularly confused at this point you might try looking at this [[analogy.html|physical analogy of a monad]] before continuing.<br />
<br />
== An example ==<br />
<br />
Suppose that we are writing a program to keep track of sheep cloning experiments. We would certainly want to know the genetic history of all of our sheep, so we would need <code>mother</code> and <code>father</code> functions. But since these are cloned sheep, they may not always have both a mother and a father!<br />
<br />
We would represent the possibility of not having a mother or father using the <code>Maybe</code> type constructor in our Haskell code:<br />
<br />
<haskell><br />
type Sheep = ...<br />
<br />
father :: Sheep -> Maybe Sheep<br />
father = ...<br />
<br />
mother :: Sheep -> Maybe Sheep<br />
mother = ...<br />
</haskell><br />
Then, defining functions to find grandparents is a little more complicated, because we have to handle the possibility of not having a parent:<br />
<br />
<haskell><br />
maternalGrandfather :: Sheep -> Maybe Sheep<br />
maternalGrandfather s = case (mother s) of<br />
Nothing -> Nothing<br />
Just m -> father m<br />
</haskell><br />
and so on for the other grandparent combinations.<br />
<br />
It gets even worse if we want to find great grandparents:<br />
<br />
<haskell><br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = case (mother s) of<br />
Nothing -> Nothing<br />
Just m -> case (father m) of<br />
Nothing -> Nothing<br />
Just gf -> father gf<br />
</haskell><br />
Aside from being ugly, unclear, and difficult to maintain, this is just too much work. It is clear that a <code>Nothing</code> value at any point in the computation will cause <code>Nothing</code> to be the final result, and it would be much nicer to implement this notion once in a single place and remove all of the explicit <code>case</code> testing scattered all over the code. This will make the code easier to write, easier to read and easier to change. So good programming style would have us create a combinator that captures the behavior we want:<br />
<br />
Code available in [[../examples/example1.hs|example1.hs]]<br />
<br />
<haskell><br />
-- comb is a combinator for sequencing operations that return Maybe<br />
comb :: Maybe a -> (a -> Maybe b) -> Maybe b<br />
comb Nothing _ = Nothing<br />
comb (Just x) f = f x<br />
<br />
-- now we can use `comb` to build complicated sequences<br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = (Just s) `comb` mother `comb` father `comb` father <br />
</haskell><br />
The combinator is a huge success! The code is much cleaner and easier to write, understand and modify. Notice also that the <code>comb</code> function is entirely polymorphic — it is not specialized for <code>Sheep</code> in any way. In fact, ''the combinator captures a general strategy for combining computations that may fail to return a value.'' Thus, we can apply the same combinator to other computations that may fail to return a value, such as database queries or dictionary lookups.<br />
<br />
The happy outcome is that common sense programming practice has led us to create a monad without even realizing it. The <code>Maybe</code> type constructor along with the <code>Just</code> function (acts like <code>return</code>) and our combinator (acts like <code>>>=</code>) together form a simple monad for building computations which may not return a value. All that remains to make this monad truly useful is to make it conform to the monad framework built into the Haskell language. That is the subject of the next chapter.<br />
<br />
== List is also a monad ==<br />
<br />
We have seen that the <code>Maybe</code> type constructor is a monad for building computations which may fail to return a value. You may be surprised to know that another common Haskell type constructor, <code>[]</code> (for building lists), is also a monad. The List monad allows us to build computations which can return 0, 1, or more values.<br />
<br />
The <code>return</code> function for lists simply creates a singleton list (<code>return x = [x]</code>). The binding operation for lists creates a new list containing the results of applying the function to all of the values in the original list (<code>l >>= f = concatMap f l</code>).<br />
<br />
One use of functions which return lists is to represent ''ambiguous'' computations — that is computations which may have 0, 1, or more allowed outcomes. In a computation composed from ambigous subcomputations, the ambiguity may compound, or it may eventually resolve into a single allowed outcome or no allowed outcome at all. During this process, the set of possible computational states is represented as a list. The List monad thus embodies a strategy for performing simultaneous computations along all allowed paths of an ambiguous computation.<br />
<br />
Examples of this use of the List monad, and contrasting examples using the Maybe monad will be presented shortly. But first, we must see how useful monads are defined in Haskell.<br />
<br />
== Summary ==<br />
<br />
We have seen that a monad is a type constructor, a function called <code>return</code>, and a combinator function called <code>bind</code> or <code>>>=</code>. These three elements work together to encapsulate a strategy for combining computations to produce more complex computations.<br />
<br />
Using the <code>Maybe</code> type constructor, we saw how good programming practice led us to define a simple monad that could be used to build complex computations out of sequences of computations that could each fail to return a value. The resulting <code>Maybe</code> monad encapsulates a strategy for combining computations that may not return values. By codifying the strategy in a monad, we have achieved a degree of modularity and flexibility that is not present when the computations are combined in an ad hoc manner.<br />
<br />
We have also seen that another common Haskell type constructor, <code>[]</code>, is a monad. The List monad encapsulates a strategy for combining computations that can return 0, 1, or multiple values.<br />
<br />
Doing it with class<br />
<br />
= Doing it with class =<br />
<br />
== Haskell type classes ==<br />
<br />
The discussion in this chapter involves the Haskell type class system. If you are not familiar with type classes in Haskell, you should [http://www.haskell.org/tutorial/classes.html review them] before continuing.<br />
<br />
== The Monad class ==<br />
<br />
In Haskell, there is a standard <code>Monad</code> class that defines the names and signatures of the two monad functions <code>return</code> and <code>>>=</code>. It is not strictly necessary to make your monads instances of the <code>Monad</code> class, but it is a good idea. Haskell has special support for <code>Monad</code> instances built into the language and making your monads instances of the <code>Monad</code> class will allow you to use these features to write cleaner and more elegant code. Also, making your monads instances of the <code>Monad</code> class communicates important information to others who read the code and failing to do so can cause you to use confusing and non-standard function names. It's easy to do and it has many benefits, so just do it!<br />
<br />
The standard <code>Monad</code> class definition in Haskell looks something like this:<br />
<br />
<haskell><br />
class Monad m where<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
return :: a -> m a<br />
</haskell><br />
== Example continued ==<br />
<br />
Continuing the [[meet.html#example1|previous example]], we will now see how the <code>Maybe</code> type constructor fits into the Haskell monad framework as an instance of the <code>Monad</code> class.<br />
<br />
Recall that our <code>Maybe</code> monad used the <code>Just</code> data constructor to fill the role of the monad <code>return</code> function and we built a simple combinator to fill the role of the monad <code>>>=</code> binding function. We can make its role as a monad explicit by declaring <code>Maybe</code> as an instance of the <code>Monad</code> class:<br />
<br />
<haskell><br />
instance Monad Maybe where<br />
Nothing >>= f = Nothing<br />
(Just x) >>= f = f x<br />
return = Just<br />
</haskell><br />
Once we have defined <code>Maybe</code> as an instance of the Monad class, we can use the standard monad operators to build the complex computations:<br />
<br />
<haskell><br />
-- we can use monadic operations to build complicated sequences<br />
maternalGrandfather :: Sheep -> Maybe Sheep<br />
maternalGrandfather s = (return s) >>= mother >>= father<br />
<br />
fathersMaternalGrandmother :: Sheep -> Maybe Sheep<br />
fathersMaternalGrandmother s = (return s) >>= father >>= mother >>= mother <br />
</haskell><br />
In Haskell, <code>Maybe</code> is defined as an instance of the <code>Monad</code> class in the standard prelude, so you don't need to do it yourself. The other monad we have seen so far, the list constructor, is also defined as an instance of the <code>Monad</code> class in the standard prelude.<br />
<br />
[[Image:info.png]] When writing functions that work with monads, try to make use of the <code>Monad</code> class instead of using a specific monad instance. A function of the type<br />
<br />
<haskell><br />
doSomething :: (Monad m) => a -> m b<br />
</haskell><br />
is much more flexible than one of the type<br />
<br />
<haskell><br />
doSomething :: a -> Maybe b<br />
</haskell><br />
The former function can be used with many types of monads to get different behavior depending on the strategy embodied in the monad, whereas the latter function is restricted to the strategy of the <code>Maybe</code> monad.<br />
<br />
== Do notation ==<br />
<br />
Using the standard monadic function names is good, but another advantage of membership in the <code>Monad</code> class is the Haskell support for &quot;do&quot; notation. Do notation is an expressive shorthand for building up monadic computations, similar to the way that list comprehensions are an expressive shorthand for building computations on lists. Any instance of the <code>Monad</code> class can be used in a do-block in Haskell.<br />
<br />
In short, the do notation allows you to write monadic computations using a pseudo-imperative style with named variables. The result of a monadic computation can be &quot;assigned&quot; to a variable using a left arrow <code><-</code> operator. Then using that variable in a subsequent monadic computation automatically performs the binding. The type of the expression to the right of the arrow is a monadic type <code>m a</code>. The expression to the left of the arrow is a pattern to be matched against the value ''inside'' the monad. <code>(x:xs)</code> would match against <code>Maybe [1,2,3]</code>, for example.<br />
<br />
Here is a sample of do notation using the <code>Maybe</code> monad:<br />
<br />
Code available in [[../examples/example2.hs|example2.hs]]<br />
<br />
<haskell><br />
-- we can also use do-notation to build complicated sequences<br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = do m <- mother s<br />
gf <- father m<br />
father gf<br />
</haskell><br />
Compare this to <code>fathersMaternalGrandmother</code> written above without using do notation.<br />
<br />
The do block shown above is written using the layout rule to define the extent of the block. Haskell also allows you to use braces and semicolons when defining a do block:<br />
<br />
<haskell><br />
mothersPaternalGrandfather s = do { m <- mother s; gf <- father m; father gf }<br />
</haskell><br />
Notice that do notation resembles an imperative programming language, in which a computation is built up from an explicit sequence of simpler computations. In this respect, monads offer the possibility to create imperative-style computations within a larger functional program. This theme will be expanded upon when we deal with side-effects and the I/O monad later.<br />
<br />
Do notation is simply syntactic sugar. There is nothing that can be done using do notation that cannot be done using only the standard monadic operators. But do notation is cleaner and more convenient in some cases, especially when the sequence of monadic computations is long. You should understand both the standard monadic binding notation and do notation and be able to apply each where they are appropriate.<br />
<br />
The actual translation from do notation to standard monadic operators is roughly that every expression matched to a pattern, <code>x <- expr1</code>, becomes<br />
<br />
<haskell><br />
expr1 >>= \x -><br />
</haskell><br />
and every expression without a variable assignment, <code>expr2</code> becomes<br />
<br />
<haskell><br />
expr2 >>= \_ -><br />
</haskell><br />
All do blocks must end with a monadic expression, and a let clause is allowed at the beginning of a do block (but let clauses in do blocks do not use the &quot;in&quot; keyword). The definition of <code>mothersPaternalGrandfather</code> above would be translated to:<br />
<br />
<haskell><br />
mothersPaternalGrandfather s = mother s >>= \m -><br />
father m >>= \gf -><br />
father gf<br />
</haskell><br />
It now becomes clear why the binding operator is so named. It is literally used to bind the value in the monad to the argument in the following lambda expression.<br />
<br />
== Summary ==<br />
<br />
Haskell provides built-in support for monads. To take advantage of Haskell's monad support, you must declare the monad type constructor to be an instance of the <code>Monad</code> class and supply definitions of the <code>return</code> and <code>>>=</code> (pronounced &quot;bind&quot;) functions for the monad.<br />
<br />
A monad that is an instance of the <code>Monad</code> class can be used with do-notation, which is syntactic sugar that provides a simple, imperative-style notation for describing computations with monads.<br />
<br />
The monad laws<br />
<br />
= The monad laws =<br />
<br />
The tutorial up to now has avoided technical discussions, but there are a few technical points that must be made concerning monads. Monadic operations must obey a set of laws, known as &quot;the monad axioms&quot;. These laws aren't enforced by the Haskell compiler, so it is up to the programmer to ensure that any <code>Monad</code> instances they declare obey the laws. Haskell's <code>Monad</code> class also includes some functions beyond the minimal complete definition that we have not seen yet. Finally, many monads obey additional laws beyond the standard monad laws, and there is an additional Haskell class to support these extended monads.<br />
<br />
== The three fundamental laws ==<br />
<br />
The concept of a monad comes from a branch of mathematics called category theory. While it is not necessary to know category theory to create and use monads, we do need to obey a small bit of mathematical formalism. To create a monad, it is not enough just to declare a Haskell instance of the <code>Monad</code> class with the correct type signatures. To be a proper monad, the <code>return</code> and <code>>>=</code> functions must work together according to three laws:<br />
<br />
# <code>(return x) >>= f == f x</code><br />
# <code>m >>= return == m</code><br />
# <code>(m >>= f) >>= g == m >>= (\x -> f x >>= g)</code><br />
<br />
The first law requires that <code>return</code> is a left-identity with respect to <code>>>=</code>. The second law requires that <code>return</code> is a right-identity with respect to <code>>>=</code>. The third law is a kind of associativity law for <code>>>=</code>. Obeying the three laws ensures that the semantics of the do-notation using the monad will be consistent.<br />
<br />
Any type constructor with return and bind operators that satisfy the three monad laws is a monad. In Haskell, the compiler does not check that the laws hold for every instance of the <code>Monad</code> class. It is up to the programmer to ensure that any <code>Monad</code> instance they create satisfies the monad laws.<br />
<br />
== Failure IS an option ==<br />
<br />
The definition of the <code>Monad</code> class given [[class.html#monad|earlier]] showed only the minimal complete definition. The full definition of the <code>Monad</code> class actually includes two additional functions: <code>fail</code> and <code>>></code>.<br />
<br />
The default implementation of the <code>fail</code> function is:<br />
<br />
<haskell><br />
fail s = error s<br />
</haskell><br />
You do not need to change this for your monad unless you want to provide different behavior for failure or to incorporate failure into the computational strategy of your monad. The <code>Maybe</code> monad, for instance, defines <code>fail</code> as:<br />
<br />
<haskell><br />
fail _ = Nothing<br />
</haskell><br />
so that <code>fail</code> returns an instance of the <code>Maybe</code> monad with meaningful behavior when it is bound with other functions in the <code>Maybe</code> monad.<br />
<br />
The <code>fail</code> function is not a required part of the mathematical definition of a monad, but it is included in the standard <code>Monad</code> class definition because of the role it plays in Haskell's do notation. The <code>fail</code> function is called whenever a pattern matching failure occurs in a do block:<br />
<br />
<haskell><br />
fn :: Int -> Maybe [Int]<br />
fn idx = do let l = [Just [1,2,3], Nothing, Just [], Just [7..20]]<br />
(x:xs) <- l!!idx -- a pattern match failure will call "fail"<br />
return xs<br />
</haskell><br />
So in the code above, <code>fn 0</code> has the value <code>Just [2,3]</code>, but <code>fn 1</code> and <code>fn 2</code> both have the value <code>Nothing</code>.<br />
<br />
The <code>>></code> function is a convenience operator that is used to bind a monadic computation that does not require input from the previous computation in the sequence. It is defined in terms of <code>>>=</code>:<br />
<br />
<haskell><br />
(>>) :: m a -> m b -> m b<br />
m >> k = m >>= (\_ -> k)<br />
</haskell><br />
== No way out ==<br />
<br />
You might have noticed that there is no way to get values out of a monad as defined in the standard <code>Monad</code> class. That is not an accident. Nothing prevents the monad author from allowing it using functions specific to the monad. For instance, values can be extracted from the <code>Maybe</code> monad by pattern matching on <code>Just x</code> or using the <code>fromJust</code> function.<br />
<br />
By not requiring such a function, the Haskell <code>Monad</code> class allows the creation of one-way monads. One-way monads allow values to enter the monad through the <code>return</code> function (and sometimes the <code>fail</code> function) and they allow computations to be performed within the monad using the bind functions <code>>>=</code> and <code>>></code>, but they do not allow values back out of the monad.<br />
<br />
The <code>IO</code> monad is a familiar example of a one-way monad in Haskell. Because you can't escape from the <code>IO</code> monad, it is impossible to write a function that does a computation in the <code>IO</code> monad but whose result type does not include the <code>IO</code> type constructor. This means that ''any'' function whose result type does not contain the <code>IO</code> type constructor is guaranteed not to use the <code>IO</code> monad. Other monads, such as <code>List</code> and <code>Maybe</code>, do allow values out of the monad. So it is possible to write functions which use these monads internally but return non-monadic values.<br />
<br />
''The wonderful feature of a one-way monad is that it can support side-effects in its monadic operations but prevent them from destroying the functional properties of the non-monadic portions of the program.''<br />
<br />
Consider the simple issue of reading a character from the user. We cannot simply have a function <code>readChar :: Char</code>, because it needs to return a different character each time it is called, depending on the input from the user. It is an essential property of Haskell as a pure functional language that all functions return the same value when called twice with the same arguments. But it ''is'' ok to have an I/O function <code>getChar :: IO Char</code> in the <code>IO</code> monad, because it can only be used in a sequence within the one-way monad. There is no way to get rid of the <code>IO</code> type constructor in the signature of any function that uses it, so the <code>IO</code> type constructor acts as a kind of tag that identifies all functions that do I/O. Furthermore, such functions are only useful within the <code>IO</code> monad. So a one-way monad effectively creates an isolated computational domain in which the rules of a pure functional language can be relaxed. Functional computations can move into the domain, but dangerous side-effects and non-referentially-transparent functions cannot escape from it.<br />
<br />
Another common pattern when defining monads is to represent monadic values as functions. Then when the value of a monadic computation is required, the resulting monad is &quot;run&quot; to provide the answer.<br />
<br />
== Zero and Plus ==<br />
<br />
Beyond the three monad laws stated above, some monads obey additional laws. The monads have a special value <code>mzero</code> and an operator <code>mplus</code> that obey four additional laws:<br />
<br />
# <code>mzero >>= f == mzero</code><br />
# <code>m >>= (\x -> mzero) == mzero</code><br />
# <code>mzero `mplus` m == m</code><br />
# <code>m `mplus` mzero == m</code><br />
<br />
It is easy to remember the laws for <code>mzero</code> and <code>mplus</code> if you associate <code>mzero</code> with 0, <code>mplus</code> with +, and <code>>>=</code> with × in ordinary arithmetic.<br />
<br />
Monads which have a zero and a plus can be declared as instances of the <code>MonadPlus</code> class in Haskell:<br />
<br />
<haskell><br />
class (Monad m) => MonadPlus m where<br />
mzero :: m a<br />
mplus :: m a -> m a -> m a<br />
</haskell><br />
Continuing to use the <code>Maybe</code> monad as an example, we see that the <code>Maybe</code> monad is an instance of <code>MonadPlus</code>:<br />
<br />
<haskell><br />
instance MonadPlus Maybe where<br />
mzero = Nothing<br />
Nothing `mplus` x = x<br />
x `mplus` _ = x<br />
</haskell><br />
This identifies <code>Nothing</code> as the zero value and says that adding two <code>Maybe</code> values together gives the first value that is not <code>Nothing</code>. If both input values are <code>Nothing</code>, then the result of <code>mplus</code> is also <code>Nothing</code>.<br />
<br />
The List monad also has a zero and a plus. <code>mzero</code> is the empty list and <code>mplus</code> is the <code>++</code> operator.<br />
<br />
The <code>mplus</code> operator is used to combine monadic values from separate computations into a single monadic value. Within the context of our sheep-cloning example, we could use <code>Maybe</code>'s <code>mplus</code> to define a function, <code>parent s = (mother s) `mplus` (father s)</code>, which would return a parent if there is one, and <code>Nothing</code> is the sheep has no parents at all. For a sheep with both parents, the function would return one or the other, depending on the exact definition of <code>mplus</code> in the <code>Maybe</code> monad.<br />
<br />
== Summary ==<br />
<br />
Instances of the <code>Monad</code> class should conform to the so-called monad laws, which describe algabraic properties of monads. There are three of these laws which state that the <code>return</code> function is both a left and a right identity and that the binding operator is associative. Failure to satisfy these laws will result in monads that do not behave properly and may cause subtle problems when using do-notation.<br />
<br />
In addition to the <code>return</code> and <code>>>=</code> functions, the <code>Monad</code> class defines another function, <code>fail</code>. The <code>fail</code> function is not a technical requirement for inclusion as a monad, but it is often useful in practice and it is included in the <code>Monad</code> class because it is used in Haskell's do-notation.<br />
<br />
Some monads obey laws beyond the three basic monad laws. An important class of such monads are ones which have a notion of a zero element and a plus operator. Haskell provides a <code>MonadPlus</code> class for such monads which define the <code>mzero</code> value and the <code>mplus</code> operator.<br />
<br />
Exercises<br />
<br />
= Exercises =<br />
<br />
# [[#exercise1|Do notation]]<br />
# [[#exercise2|Combining monadic values]]<br />
# [[#exercise3|Using the List monad]]<br />
# [[#exercise4|Using the Monad class constraint]]<br />
<br />
This section contains a few simple exercises to hone the reader's monadic reasoning skills and to provide a solid comprehension of the function and use of the Maybe and List monads before looking at monadic programming in more depth. The exercises will build on the previous sheep-cloning [[../examples/example2.hs|example]], with which the reader should already be familiar.<br />
<br />
== Exercise 1: Do notation ==<br />
<br />
Rewrite the <code>maternalGrandfather</code>, <code>fathersMaternalGrandmother</code>, and <code>mothersPaternalGrandfather</code> functions in [[../examples/example2.hs|Example 2]] using the monadic operators <code>return</code> and <code>>>=</code>, without using any do-notation syntactic sugar.<br />
<br />
<br />
<br />
Click [[solution1.html|here]] to see the solution.<br />
<br />
== Exercise 2: Combining monadic values ==<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>Sheep -> Maybe Sheep</code>. They should return one sheep selected from all sheep matching the description, or <code>Nothing</code> if there is no such sheep. Hint: the <code>mplus</code> operator is useful here.<br />
<br />
Click [[solution2.html|here]] to see the solution.<br />
<br />
== Exercise 3: Using the List monad ==<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>Sheep -> [Sheep]</code>. They should return all sheep matching the description, or the empty list if there is no such sheep. Hint: the <code>mplus</code> operator in the List monad is useful here. Also the <code>maybeToList</code> function in the <code>Maybe</code> module can be used to convert a value from the Maybe monad to the List monad.<br />
<br />
Click [[solution3.html|here]] to see the solution.<br />
<br />
== Exercise 4: Using the Monad class constraint ==<br />
<br />
Monads promote modularity and code reuse by encapsulating often-used computational strategies into single blocks of code that can be used to construct many different computations. Less obviously, monads also promote modularity by allowing you to vary the monad in which a computation is done to achieve different variations of the computation. This is achieved by writing functions which are polymorphic in the monad type constructor, using the <code>(Monad m) =></code>, <code>(MonadPlus m) =></code>, etc. class constraints.<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>(MonadPlus m) => Sheep -> m Sheep</code>. They should be useful in both the Maybe and List monads. How does the functions' behavior differ when used with the List monad versus the Maybe monad? If you need to review the use of type classes and class constraints in Haskell, look [http://www.haskell.org/tutorial/classes.html here].<br />
<br />
Click [[solution4.html|here]] to see the solution.<br />
<br />
Monad support in Haskell<br />
<br />
= Monad support in Haskell =<br />
<br />
Haskell's built in support for monads is split among the standard prelude, which exports the most common monad functions, and the Monad module, which contains less-commonly used monad functions. The individual monad types are each in their own libraries and are the subject of [[introII.html|Part II]] of this tutorial.<br />
<br />
== In the standard prelude ==<br />
<br />
The Haskell 98 [http://www.haskell.org/onlinelibrary/standard-prelude.html standard prelude] includes the definition of the <code>Monad</code> class as well as a few auxilliary functions for working with monadic data types.<br />
<br />
=== The <code>Monad</code> class ===<br />
<br />
We have seen the <code>Monad</code> class before:<br />
<br />
<haskell><br />
class Monad m where<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
(>>) :: m a -> m b -> m b<br />
return :: a -> m a<br />
fail :: String -> m a<br />
<br />
-- Minimal complete definition:<br />
-- (>>=), return<br />
m >> k = m >>= \_ -> k<br />
fail s = error s<br />
</haskell><br />
=== The sequencing functions ===<br />
<br />
The <code>sequence</code> function takes a list of monadic computations, executes each one in turn and returns a list of the results. If any of the computations fail, then the whole function fails:<br />
<br />
<haskell><br />
sequence :: Monad m => [m a] -> m [a] <br />
sequence = foldr mcons (return [])<br />
where mcons p q = p >>= \x -> q >>= \y -> return (x:y)<br />
</haskell><br />
The <code>sequence_</code> function (notice the underscore) has the same behavior as <code>sequence</code> but does not return a list of results. It is useful when only the side-effects of the monadic computations are important.<br />
<br />
<haskell><br />
sequence_ :: Monad m => [m a] -> m () <br />
sequence_ = foldr (>>) (return ())<br />
</haskell><br />
=== The mapping functions ===<br />
<br />
The <code>mapM</code> function maps a monadic computation over a list of values and returns a list of the results. It is defined in terms of the list <code>map</code> function and the <code>sequence</code> function above:<br />
<br />
<haskell><br />
mapM :: Monad m => (a -> m b) -> [a] -> m [b] <br />
mapM f as = sequence (map f as)<br />
</haskell><br />
There is also a version with an underscore, <code>mapM_</code> which is defined using sequence_. <code>mapM_</code> operates the same as <code>mapM</code>, but it doesn't return the list of values. It is useful when only the side-effects of the monadic computation are important.<br />
<br />
<haskell><br />
mapM_ :: Monad m => (a -> m b) -> [a] -> m () <br />
mapM_ f as = sequence_ (map f as)<br />
</haskell><br />
As a simple example of the use the mapping functions, a <code>putString</code> function for the <code>IO</code> monad could be defined as:<br />
<br />
<haskell><br />
putString :: [Char] -> IO ()<br />
putString s = mapM_ putChar s<br />
</haskell><br />
<code>mapM</code> can be used within a do block in a manner similar to the way the <code>map</code> function is normally used on lists. This is a common pattern with monads — a version of a function for use within a monad (i.e., intended for binding) will have a signature similar to the non-monadic version but the function outputs will be within the monad:<br />
<br />
<haskell><br />
-- compare the non-monadic and monadic signatures<br />
map :: (a -> b) -> [a] -> [b]<br />
mapM :: Monad m => (a -> m b) -> [a] -> m [b] <br />
</haskell><br />
=== The reverse binder function (<code>=<<</code>) ===<br />
<br />
The prelude also defines a binding function that takes it arguments in the opposite order to the standard binding function. Since the standard binding function is called &quot;<code>>>=</code>&quot;, the reverse binding function is called &quot;<code>=<<</code>&quot;. It is useful in circumstances where the binding operator is used as a higher-order term and it is more convenient to have the arguments in the reversed order. Its definition is simply:<br />
<br />
<haskell><br />
(=<<) :: Monad m => (a -> m b) -> m a -> m b<br />
f =<< x = x >>= f<br />
</haskell><br />
== In the Monad module ==<br />
<br />
The <code>Monad</code> module in the standard Haskell 98 libraries exports a number of facilities for more advanced monadic operations. To access these facilities, simply <code>import Monad</code> in your Haskell program.<br />
<br />
Not all of the function in the <code>Monad</code> module are discussed here, but you are encouraged to [http://www.haskell.org/onlinelibrary/monad.html explore the module for yourself] when you feel you are ready to see some of the more esoteric monad functions.<br />
<br />
=== The <code>MonadPlus</code> class ===<br />
<br />
The <code>Monad</code> module defines the <code>MonadPlus</code> class for monads with a zero element and a plus operator:<br />
<br />
<haskell><br />
class Monad m => MonadPlus m where<br />
mzero :: m a<br />
mplus :: m a -> m a -> m a<br />
</haskell><br />
=== Monadic versions of list functions ===<br />
<br />
Several functions are provided which generalize standard list-processing functions to monads. The <code>mapM</code> functions are exported in the standard prelude and were described above.<br />
<br />
<code>foldM</code> is a monadic version of <code>foldl</code> in which monadic computations built from a list are bound left-to-right. The definition is:<br />
<br />
<haskell><br />
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a<br />
foldM f a [] = return a<br />
foldM f a (x:xs) = f a x >>= \y -> foldM f y xs<br />
</haskell><br />
but it is easier to understand the operation of <code>foldM</code> if you consider its effect in terms of a do block:<br />
<br />
<haskell><br />
-- this is not valid Haskell code, it is just for illustration<br />
foldM f a1 [x1,x2,...,xn] = do a2 <- f a1 x1<br />
a3 <- f a2 x2<br />
...<br />
f an xn<br />
</haskell><br />
Right-to-left binding is achieved by reversing the input list before calling <code>foldM</code>.<br />
<br />
We can use <code>foldM</code> to create a more poweful query function in our sheep cloning example:<br />
<br />
Code available in [[../examples/example3.hs|example3.hs]]<br />
<br />
<haskell><br />
-- traceFamily is a generic function to find an ancestor<br />
traceFamily :: Sheep -> [ (Sheep -> Maybe Sheep) ] -> Maybe Sheep<br />
traceFamily s l = foldM getParent s l<br />
where getParent s f = f s<br />
<br />
-- we can define complex queries using traceFamily in an easy, clear way<br />
mothersPaternalGrandfather s = traceFamily s [mother, father, father]<br />
paternalGrandmother s = traceFamily s [father, mother]<br />
</haskell><br />
The <code>traceFamily</code> function uses <code>foldM</code> to create a simple way to trace back in the family tree to any depth and in any pattern. In fact, it is probably clearer to write &quot;<code>traceFamily s [father, mother]</code>&quot; than it is to use the <code>paternalGrandmother</code> function!<br />
<br />
A more typical use of <code>foldM</code> is within a do block:<br />
<br />
Code available in [[../examples/example4.hs|example4.hs]]<br />
<br />
<haskell><br />
-- a Dict is just a finite map from strings to strings<br />
type Dict = FiniteMap String String<br />
<br />
-- this an auxilliary function used with foldl<br />
addEntry :: Dict -> Entry -> Dict<br />
addEntry d e = addToFM d (key e) (value e)<br />
<br />
-- this is an auxiliiary function used with foldM inside the IO monad<br />
addDataFromFile :: Dict -> Handle -> IO Dict<br />
addDataFromFile dict hdl = do contents <- hGetContents hdl<br />
entries <- return (map read (lines contents))<br />
return (foldl (addEntry) dict entries)<br />
<br />
-- this program builds a dictionary from the entries in all files named on the<br />
-- command line and then prints it out as an association list<br />
main :: IO ()<br />
main = do files <- getArgs<br />
handles <- mapM openForReading files<br />
dict <- foldM addDataFromFile emptyFM handles<br />
print (fmToList dict)<br />
</haskell><br />
The <code>filterM</code> function works like the list <code>filter</code> function inside of a monad. It takes a predicate function which returns a Boolean value in the monad and a list of values. It returns, inside the monad, a list of those values for which the predicate was True.<br />
<br />
<haskell><br />
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]<br />
filterM p [] = return []<br />
filterM p (x:xs) = do b <- p x<br />
ys <- filterM p xs<br />
return (if b then (x:ys) else ys)<br />
</haskell><br />
Here is an example showing how <code>filterM</code> can be used within the <code>IO</code> monad to select only the directories from a list:<br />
<br />
Code available in [[../examples/example5.hs|example5.hs]]<br />
<br />
<haskell><br />
import Monad<br />
import Directory<br />
import System<br />
<br />
-- NOTE: doesDirectoryExist has type FilePath -> IO Bool<br />
<br />
-- this program prints only the directories named on the command line<br />
main :: IO ()<br />
main = do names <- getArgs<br />
dirs <- filterM doesDirectoryExist names<br />
mapM_ putStrLn dirs<br />
</haskell><br />
<code>zipWithM</code> is a monadic version of the <code>zipWith</code> function on lists. <code>zipWithM_</code> behaves the same but discards the output of the function. It is useful when only the side-effects of the monadic computation matter.<br />
<br />
<haskell><br />
zipWithM ::(Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]<br />
zipWithM f xs ys = sequence (zipWith f xs ys)<br />
<br />
zipWithM_ ::(Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()<br />
zipWithM_ f xs ys = sequence_ (zipWith f xs ys)<br />
</haskell><br />
=== Conditional monadic computations ===<br />
<br />
There are two functions provided for conditionally executing monadic computations. The <code>when</code> function takes a boolean argument and a monadic computation with unit &quot;()&quot; type and performs the computation only when the boolean argument is <code>True</code>. The <code>unless</code> function does the same, except that it performs the computation ''unless'' the boolean argument is <code>True</code>.<br />
<br />
<haskell><br />
when :: (Monad m) => Bool -> m () -> m ()<br />
when p s = if p then s else return ()<br />
<br />
unless :: (Monad m) => Bool -> m () -> m ()<br />
unless p s = when (not p) s<br />
</haskell><br />
=== <code>ap</code> and the lifting functions ===<br />
<br />
''Lifting'' is a monadic operation that converts a non-monadic function into an equivalent function that operates on monadic values. We say that a function is &quot;lifted into the monad&quot; by the lifting operators. A lifted function is useful for operating on monad values outside of a do block and can also allow for cleaner code within a do block.<br />
<br />
The simplest lifting operator is <code>liftM</code>, which lifts a function of a single argument into a monad.<br />
<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> (m a -> m b)<br />
liftM f = \a -> do { a' <- a; return (f a') }<br />
</haskell><br />
Lifting operators are also provided for functions with more arguments. <code>liftM2</code> lifts functions of two arguments:<br />
<br />
<haskell><br />
liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)<br />
liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') }<br />
</haskell><br />
The same pattern is applied to give the definitions to lift functions of more arguments. Functions up to <code>liftM5</code> are defined in the <code>Monad</code> module.<br />
<br />
To see how the lifting operators allow more concise code, consider a computation in the <code>Maybe</code> monad in which you want to use a function <code>swapNames::String -> String</code>. You could do:<br />
<br />
<haskell><br />
getName :: String -> Maybe String<br />
getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]<br />
tempName <- lookup name db<br />
return (swapNames tempName)<br />
</haskell><br />
But making use of the <code>liftM</code> function, we can use <code>liftM swapNames</code> as a function of type <code>Maybe String -> Maybe String</code>:<br />
<br />
Code available in [[../examples/example6.hs|example6.hs]]<br />
<br />
<haskell><br />
getName :: String -> Maybe String<br />
getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]<br />
liftM swapNames (lookup name db)<br />
</haskell><br />
The difference is even greater when lifting functions with more arguments.<br />
<br />
The lifting functions also enable very concise constructions using higher-order functions. To understand this example code, you might need to review the definition of the monad functions for the [[listmonad.html#definition|List monad]] (particularly <code>>>=</code>). Imagine how you might implement this function without lifting the operator:<br />
<br />
Code available in [[../examples/example7.hs|example7.hs]]<br />
<br />
<haskell><br />
-- allCombinations returns a list containing the result of<br />
-- folding the binary operator through all combinations<br />
-- of elements of the given lists<br />
-- For example, allCombinations (+) [[0,1],[1,2,3]] would be<br />
-- [0+1,0+2,0+3,1+1,1+2,1+3], or [1,2,3,2,3,4]<br />
-- and allCombinations (*) [[0,1],[1,2],[3,5]] would be<br />
-- [0*1*3,0*1*5,0*2*3,0*2*5,1*1*3,1*1*5,1*2*3,1*2*5], or [0,0,0,0,3,5,6,10]<br />
allCombinations :: (a -> a -> a) -> [[a]] -> [a]<br />
allCombinations fn [] = []<br />
allCombinations fn (l:ls) = foldl (liftM2 fn) l ls<br />
</haskell><br />
There is a related function called <code>ap</code> that is sometimes more convenient to use than the lifting functions. <code>ap</code> is simply the function application operator (<code>$</code>) lifted into the monad:<br />
<br />
<haskell><br />
ap :: (Monad m) => m (a -> b) -> m a -> m b<br />
ap = liftM2 ($)<br />
</haskell><br />
Note that <code>liftM2 f x y</code> is equivalent to <code>return f `ap` x `ap` y</code>, and so on for functions of more arguments. <code>ap</code> is useful when working with higher-order functions and monads.<br />
<br />
The effect of <code>ap</code> depends on the strategy of the monad in which it is used. So for example <code>[(*2),(+3)] `ap` [0,1,2]</code> is equal to <code>[0,2,4,3,4,5]</code> and <code>(Just (*2)) `ap` (Just 3)</code> is <code>Just 6</code>. Here is a simple example that shows how <code>ap</code> can be useful when doing higher-order computations:<br />
<br />
Code available in [[../examples/example8.hs|example8.hs]]<br />
<br />
<haskell><br />
-- lookup the commands and fold ap into the command list to<br />
-- compute a result.<br />
main :: IO ()<br />
main = do let fns = [("double",(2*)), ("halve",(`div`2)),<br />
("square",(\x->x*x)), ("negate", negate),<br />
("incr",(+1)), ("decr",(+(-1)))<br />
]<br />
args <- getArgs<br />
let val = read (args!!0)<br />
cmds = map ((flip lookup) fns) (words (args!!1))<br />
print $ foldl (flip ap) (Just val) cmds<br />
</haskell><br />
=== Functions for use with <code>MonadPlus</code> ===<br />
<br />
There are two functions in the <code>Monad</code> module that are used with monads that have a zero and a plus. The first function is <code>msum</code>, which is analogous to the <code>sum</code> function on lists of integers. <code>msum</code> operates on lists of monadic values and folds the <code>mplus</code> operator into the list using the <code>mzero</code> element as the initial value:<br />
<br />
<haskell><br />
msum :: MonadPlus m => [m a] -> m a<br />
msum xs = foldr mplus mzero xs<br />
</haskell><br />
In the List monad, <code>msum</code> is equivalent to <code>concat</code>. In the <code>Maybe</code> monad, <code>msum</code> returns the first non-<code>Nothing</code> value from a list. Likewise, the behavior in other monads will depend on the exact nature of their <code>mzero</code> and <code>mplus</code> definitions.<br />
<br />
<code>msum</code> allows many recursive functions and folds to be expressed more concisely. In the <code>Maybe</code> monad, for example, we can write:<br />
<br />
Code available in [[../examples/example9.hs|example9.hs]]<br />
<br />
<haskell><br />
type Variable = String<br />
type Value = String<br />
type EnvironmentStack = [[(Variable,Value)]]<br />
<br />
-- lookupVar retrieves a variable's value from the environment stack<br />
-- It uses msum in the Maybe monad to return the first non-Nothing value.<br />
lookupVar :: Variable -> EnvironmentStack -> Maybe Value<br />
lookupVar var stack = msum $ map (lookup var) stack<br />
</haskell><br />
instead of:<br />
<br />
<haskell><br />
lookupVar :: Variable -> EnvironmentStack -> Maybe Value<br />
lookupVar var [] = Nothing<br />
lookupVar var (e:es) = let val = lookup var e<br />
in maybe (lookupVar var es) Just val<br />
</haskell><br />
The second function for use with monads with a zero and a plus is the <code>guard</code> function:<br />
<br />
<haskell><br />
guard :: MonadPlus m => Bool -> m ()<br />
guard p = if p then return () else mzero<br />
</haskell><br />
The trick to understanding this function is to recall the law for monads with zero and plus that states <code>mzero >>= f == mzero</code>. So, placing a <code>guard</code> function in a sequence of monadic operations will force any execution in which the guard is <code>False</code> to be <code>mzero</code>. This is similar to the way that guard predicates in a list comprehension cause values that fail the predicate to become <code>[]</code>.<br />
<br />
Here is an example demonstrating the use of the <code>guard</code> function in the <code>Maybe</code> monad.<br />
<br />
Code available in [[../examples/example10.hs|example10.hs]]<br />
<br />
<haskell><br />
data Record = Rec {name::String, age::Int} deriving Show<br />
type DB = [Record]<br />
<br />
-- getYoungerThan returns all records for people younger than a specified age.<br />
-- It uses the guard function to eliminate records for ages at or over the limit.<br />
-- This is just for demonstration purposes. In real life, it would be<br />
-- clearer to simply use filter. When the filter criteria are more complex,<br />
-- guard becomes more useful.<br />
getYoungerThan :: Int -> DB -> [Record]<br />
getYoungerThan limit db = mapMaybe (\r -> do { guard (age r < limit); return r }) db<br />
</haskell><br />
== Summary ==<br />
<br />
Haskell provides a number of functions which are useful for working with monads in the standard libraries. The <code>Monad</code> class and most common monad functions are in the standard prelude. The <code>MonadPlus</code> class and less commonly-used (but still very useful!) functions are defined in the <code>Monad</code> module. Many other types in the Haskell libraries are declared as instances of <code>Monad</code> and <code>MonadPlus</code> in their respective modules.<br />
<br />
Part II - Introduction<br />
<br />
= Introduction =<br />
<br />
The monads covered in Part II include a mixture of standard Haskell types that are monads as well as monad classes from Andy Gill's Monad Template Library. The Monad Template Library is included in the Glasgow Haskell Compiler's hierarchical libraries under [http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.html Control.Monad]<br />
<br />
Some of the documentation for these monads comes from the excellent [http://www.haskell.org/hawiki Haskell Wiki]. In addition to the monads covered here, monads appear many other places in Haskell, such as the [http://www.cs.uu.nl/people/daan/papers/parsec.html Parsec] monadic combinator parsing library. These monads are beyond the scope of this reference, but they are thoroughly documented on their own. You can get a taste of the Parsec library by looking in the [[../examples/example16.hs|source code]] for [[readermonad.html#example|example 16]].<br />
<br />
<table><br />
<thead><br />
<tr class="header"><br />
<th align="left">Monad</th><br />
<th align="left">Type of computation</th><br />
<th align="left">Combination strategy for <code>>>=</code></th><br />
</tr><br />
</thead><br />
<tbody><br />
<tr class="odd"><br />
<td align="left">[[identitymonad.html|Identity]]</td><br />
<td align="left">''N/A — Used with monad transformers''</td><br />
<td align="left">The bound function is applied to the input value.</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[maybemonad.html|Maybe]]</td><br />
<td align="left">Computations which may not return a result</td><br />
<td align="left"><code>Nothing</code> input gives <code>Nothing</code> output<br /><br />
<code>Just x</code> input uses <code>x</code> as input to the bound function.</td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[errormonad.html|Error]]</td><br />
<td align="left">Computations which can fail or throw exceptions</td><br />
<td align="left">Failure records information describing the failure. Binding passes failure information on without executing the bound function, or uses successful values as input to the bound function.</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[listmonad.html|[] (List)]]</td><br />
<td align="left">Non-deterministic computations which can return multiple possible results</td><br />
<td align="left">Maps the bound function onto the input list and concatenates the resulting lists to get a list of all possible results from all possible inputs.</td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[iomonad.html|IO]]</td><br />
<td align="left">Computations which perform I/O</td><br />
<td align="left">Sequential execution of I/O actions in the order of binding.</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[statemonad.html|State]]</td><br />
<td align="left">Computations which maintain state</td><br />
<td align="left">The bound function is applied to the input value to produce a state transition function which is applied to the input state.</td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[readermonad.html|Reader]]</td><br />
<td align="left">Computations which read from a shared environment</td><br />
<td align="left">The bound function is applied to the value of the input using the same environment.</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[writermonad.html|Writer]]</td><br />
<td align="left">Computations which write data in addition to computing values</td><br />
<td align="left">Written data is maintained separately from values. The bound function is applied to the input value and anything it writes is appended to the write data stream.</td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[contmonad.html|Cont]]</td><br />
<td align="left">Computations which can be interrupted and restarted</td><br />
<td align="left">The bound function is inserted into the continuation chain.</td><br />
</tr><br />
</tbody><br />
</table><br />
<br />
The Identity monad<br />
<br />
= The Identity monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Simple function application<br />
<br />
Binding strategy:<br />
<br />
The bound function is applied to the input value. <code>Identity x >>= f == Identity (f x)</code><br />
<br />
Useful for:<br />
<br />
Monads can be derived from monad transformers applied to the Identity monad.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Identity.html Identity a]<br />
<br />
== Motivation ==<br />
<br />
The Identity monad is a monad that does not embody any computational strategy. It simply applies the bound function to its input without any modification. Computationally, there is no reason to use the Identity monad instead of the much simpler act of simply applying functions to their arguments. The purpose of the Identity monad is its fundamental role in the theory of monad transformers (covered in Part III). Any monad transformer applied to the Identity monad yields a non-transformer version of that monad.<br />
<br />
== Definition ==<br />
<br />
<haskell><br />
newtype Identity a = Identity { runIdentity :: a } <br />
<br />
instance Monad Identity where<br />
return a = Identity a -- i.e. return = id <br />
(Identity x) >>= f = f x -- i.e. x >>= f = f x <br />
</haskell><br />
The <code>runIdentity</code> label is used in the type definition because it follows a style of monad definition that explicitly represents monad values as computations. In this style, a monadic computation is built up using the monadic operators and then the value of the computation is extracted using the <code>run******</code> function. Because the Identity monad does not do any computation, its definition is trivial. For a better example of this style of monad, see the [[statemonad.html|State]] monad.<br />
<br />
== Example ==<br />
<br />
A typical use of the Identity monad is to derive a monad from a monad transformer.<br />
<br />
<haskell><br />
-- derive the State monad using the StateT monad transformer<br />
type State s a = StateT s Identity a<br />
</haskell><br />
The Maybe monad<br />
<br />
= The Maybe monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which may return <code>Nothing</code><br />
<br />
Binding strategy:<br />
<br />
<code>Nothing</code> values bypass the bound function, other values are used as inputs to the bound function.<br />
<br />
Useful for:<br />
<br />
Building computations from sequences of functions that may return <code>Nothing</code>. Complex database queries or dictionary lookups are good examples.<br />
<br />
Zero and plus:<br />
<br />
<code>Nothing</code> is the zero. The plus operation returns the first non-<code>Nothing</code> value or <code>Nothing</code> if both inputs are <code>Nothing</code>.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/onlinelibrary/maybe.html Maybe a]<br />
<br />
== Motivation ==<br />
<br />
The Maybe monad embodies the strategy of combining a chain of computations that may each return <code>Nothing</code> by ending the chain early if any step produces <code>Nothing</code> as output. It is useful when a computation entails a sequence of steps that depend on one another, and in which some steps may fail to return a value.<br />
<br />
[[Image:info.png]] If you ever find yourself writing code like this:<br /><br />
<br />
<br />
<haskell><br />
case ... of<br />
Nothing -> Nothing<br />
Just x -> case ... of<br />
Nothing -> Nothing<br />
Just y -> ...<br />
</haskell><br />
you should consider using the monadic properties of <code>Maybe</code> to improve the code.<br />
<br />
== Definition ==<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
<br />
instance Monad Maybe where<br />
return = Just<br />
fail = Nothing<br />
Nothing >>= f = Nothing<br />
(Just x) >>= f = f x<br />
<br />
instance MonadPlus Maybe where<br />
mzero = Nothing<br />
Nothing `mplus` x = x<br />
x `mplus` _ = x<br />
</haskell><br />
== Example ==<br />
<br />
A common example is in combining dictionary lookups. Given a dictionary that maps full names to email addresses, another that maps nicknames to email addresses, and a third that maps email addresses to email preferences, you could create a function that finds a person's email preferences based on either a full name or a nickname.<br />
<br />
Code available in [[../examples/example11.hs|example11.hs]]<br />
<br />
<haskell><br />
data MailPref = HTML | Plain<br />
data MailSystem = ...<br />
<br />
getMailPrefs :: MailSystem -> String -> Maybe MailPref<br />
getMailPrefs sys name =<br />
do let nameDB = fullNameDB sys<br />
nickDB = nickNameDB sys<br />
prefDB = prefsDB sys<br />
addr <- (lookup name nameDB) `mplus` (lookup name nickDB)<br />
lookup addr prefDB<br />
</haskell><br />
The Error monad<br />
<br />
= The Error monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which may fail or throw exceptions<br />
<br />
Binding strategy:<br />
<br />
Failure records information about the cause/location of the failure. Failure values bypass the bound function, other values are used as inputs to the bound function.<br />
<br />
Useful for:<br />
<br />
Building computations from sequences of functions that may fail or using exception handling to structure error handling.<br />
<br />
Zero and plus:<br />
<br />
Zero is represented by an empty error and the plus operation executes its second argument if the first fails.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/onlinelibrary/standard-prelude.html#$tEither Either String a]<br />
<br />
== Motivation ==<br />
<br />
The Error monad (also called the Exception monad) embodies the strategy of combining computations that can throw exceptions by bypassing bound functions from the point an exception is thrown to the point that it is handled.<br />
<br />
The [http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Error.html <code>MonadError</code>] class is parameterized over the type of error information and the monad type constructor. It is common to use <code>Either String</code> as the monad type constructor for an error monad in which error descriptions take the form of strings. In that case and many other common cases the resulting monad is already defined as an instance of the <code>MonadError</code> class. You can also define your own error type and/or use a monad type constructor other than <code>Either String</code> or <code>Either IOError</code>. In these cases you will have to explicitly define instances of the <code>Error</code> and/or <code>MonadError</code> classes.<br />
<br />
== Definition ==<br />
<br />
The definition of the <code>MonadError</code> class below uses multi-parameter type classes and funDeps, which are language extensions not found in standard Haskell 98. You don't need to understand them to take advantage of the <code>MonadError</code> class.<br />
<br />
<haskell><br />
class Error a where<br />
noMsg :: a<br />
strMsg :: String -> a<br />
<br />
class (Monad m) => MonadError e m | m -> e where<br />
throwError :: e -> m a<br />
catchError :: m a -> (e -> m a) -> m a<br />
</haskell><br />
<code>throwError</code> is used within a monadic computation to begin exception processing. <code>catchError</code> provides a handler function to handle previous errors and return to normal execution. A common idiom is:<br />
<br />
<haskell><br />
do { action1; action2; action3 } `catchError` handler <br />
</haskell><br />
where the <code>action</code> functions can call <code>throwError</code>. Note that <code>handler</code> and the do-block must have the same return type.<br />
<br />
The definition of the <code>Either e</code> type constructor as an instance of the <code>MonadError</code> class is straightforward. Following convention, <code>Left</code> is used for error values and <code>Right</code> is used for non-error (right) values.<br />
<br />
<br />
<br />
<haskell><br />
instance MonadError (Either e) where <br />
throwError = Left <br />
(Left e) `catchError` handler = handler e <br />
a `catchError` _ = a <br />
</haskell><br />
== Example ==<br />
<br />
Here is an example that demonstrates the use of a custom <code>Error</code> data type with the <code>ErrorMonad</code>'s <code>throwError</code> and <code>catchError</code> exception mechanism. The example attempts to parse hexadecimal numbers and throws an exception if an invalid character is encountered. We use a custom <code>Error</code> data type to record the location of the parse error. The exception is caught by a calling function and handled by printing an informative error message.<br />
<br />
Code available in [[../examples/example12.hs|example12.hs]]<br />
<br />
<haskell><br />
-- This is the type of our parse error representation.<br />
data ParseError = Err {location::Int, reason::String}<br />
<br />
-- We make it an instance of the Error class<br />
instance Error ParseError where<br />
noMsg = Err 0 "Parse Error"<br />
strMsg s = Err 0 s<br />
<br />
-- For our monad type constructor, we use Either ParseError<br />
-- which represents failure using Left ParseError or a<br />
-- successful result of type a using Right a.<br />
type ParseMonad = Either ParseError<br />
<br />
-- parseHexDigit attempts to convert a single hex digit into<br />
-- an Integer in the ParseMonad monad and throws an error on an<br />
-- invalid character<br />
parseHexDigit :: Char -> Int -> ParseMonad Integer<br />
parseHexDigit c idx = if isHexDigit c then<br />
return (toInteger (digitToInt c))<br />
else<br />
throwError (Err idx ("Invalid character '" ++ [c] ++ "'"))<br />
<br />
-- parseHex parses a string containing a hexadecimal number into<br />
-- an Integer in the ParseMonad monad. A parse error from parseHexDigit<br />
-- will cause an exceptional return from parseHex.<br />
parseHex :: String -> ParseMonad Integer<br />
parseHex s = parseHex' s 0 1<br />
where parseHex' [] val _ = return val<br />
parseHex' (c:cs) val idx = do d <- parseHexDigit c idx<br />
parseHex' cs ((val * 16) + d) (idx + 1)<br />
<br />
-- toString converts an Integer into a String in the ParseMonad monad<br />
toString :: Integer -> ParseMonad String<br />
toString n = return $ show n<br />
<br />
-- convert takes a String containing a hexadecimal representation of<br />
-- a number to a String containing a decimal representation of that<br />
-- number. A parse error on the input String will generate a<br />
-- descriptive error message as the output String.<br />
convert :: String -> String<br />
convert s = let (Right str) = do {n <- parseHex s; toString n} `catchError` printError<br />
in str<br />
where printError e = return $ "At index " ++ (show (location e)) ++ ":" ++ (reason e)<br />
</haskell><br />
The List monad<br />
<br />
= The List monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which may return 0, 1, or more possible results.<br />
<br />
Binding strategy:<br />
<br />
The bound function is applied to all possible values in the input list and the resulting lists are concatenated to produce a list of all possible results.<br />
<br />
Useful for:<br />
<br />
Building computations from sequences of non-deterministic operations. Parsing ambiguous grammars is a common example.<br />
<br />
Zero and plus:<br />
<br />
<code>[]</code> is the zero and <code>++</code> is the plus operation.<br />
<br />
Example type:<br />
<br />
<code>[a]</code><br />
<br />
== Motivation ==<br />
<br />
The List monad embodies the strategy of combining a chain of non-deterministic computations by applying the operations to all possible values at each step. It is useful when computations must deal with ambiguity. In that case it allows all possibilities to be explored until the ambiguity is resolved.<br />
<br />
== Definition ==<br />
<br />
<haskell><br />
instance Monad [] where<br />
m >>= f = concatMap f m<br />
return x = [x]<br />
fail s = []<br />
<br />
instance MonadPlus [] where<br />
mzero = []<br />
mplus = (++)<br />
</haskell><br />
== Example ==<br />
<br />
The canonical example of using the List monad is for parsing ambiguous grammars. The example below shows just a small example of parsing data into hex values, decimal values and words containing only alpha-numeric characters. Note that hexadecimal digits overlap both decimal digits and alphanumeric characters, leading to an ambiguous grammar. &quot;dead&quot; is both a valid hex value and a word, for example, and &quot;10&quot; is both a decimal value of 10 and a hex value of 16.<br />
<br />
Code available in [[../examples/example13.hs|example13.hs]]<br />
<br />
<haskell><br />
-- we can parse three different types of terms<br />
data Parsed = Digit Integer | Hex Integer | Word String deriving Show<br />
<br />
-- attempts to add a character to the parsed representation of a hex digit<br />
parseHexDigit :: Parsed -> Char -> [Parsed]<br />
parseHexDigit (Hex n) c = if isHexDigit c then<br />
return (Hex ((n*16) + (toInteger (digitToInt c))))<br />
else<br />
mzero<br />
parseHexDigit _ _ = mzero<br />
<br />
-- attempts to add a character to the parsed representation of a decimal digit<br />
parseDigit :: Parsed -> Char -> [Parsed]<br />
parseDigit (Digit n) c = if isDigit c then<br />
return (Digit ((n*10) + (toInteger (digitToInt c))))<br />
else<br />
mzero<br />
parseDigit _ _ = mzero<br />
<br />
-- attempts to add a character to the parsed representation of a word<br />
parseWord :: Parsed -> Char -> [Parsed]<br />
parseWord (Word s) c = if isAlpha c then<br />
return (Word (s ++ [c]))<br />
else<br />
mzero<br />
parseWord _ _ = mzero<br />
<br />
-- tries to parse the digit as a hex value, a decimal value and a word<br />
-- the result is a list of possible parses<br />
parse :: Parsed -> Char -> [Parsed]<br />
parse p c = (parseHexDigit p c) `mplus` (parseDigit p c) `mplus` (parseWord p c)<br />
<br />
-- parse an entire String and return a list of the possible parsed values<br />
parseArg :: String -> [Parsed]<br />
parseArg s = do init <- (return (Hex 0)) `mplus` (return (Digit 0)) `mplus` (return (Word ""))<br />
foldM parse init s<br />
</haskell><br />
The IO monad<br />
<br />
= The IO monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which perform I/O<br />
<br />
Binding strategy:<br />
<br />
I/O actions are executed in the order in which they are bound. Failures throw I/O errors which can be caught and handled.<br />
<br />
Useful for:<br />
<br />
Performing I/O within a Haskell program.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/onlinelibrary/io.html IO a]<br />
<br />
== Motivation ==<br />
<br />
Input/Output is incompatible with a pure functional language because it is not referentially transparent and side-effect free. The IO monad solves this problem by confining computations that perform I/O within the IO monad.<br />
<br />
== Definition ==<br />
<br />
The definition of the IO monad is platform-specific. No data constructors are exported and no functions are provided to remove data from the IO monad. This makes the IO monad a one-way monad and is essential to ensuring safety of functional programs by isolating side-effects and non-referentially transparent actions within the imperative-style computations of the IO monad.<br />
<br />
Throughout this tutorial, we have referred to monadic values as computations. However, values in the IO monad are often called I/O actions and we will use that terminology here.<br />
<br />
In Haskell, the top-level <code>main</code> function must have type <code>IO ()</code>, so that programs are typically structured at the top level as an imperative-style sequence of I/O actions and calls to functional-style code. The functions exported from the <code>IO</code> module do not perform I/O themselves. They return I/O actions, which describe an I/O operation to be performed. The I/O actions are combined within the IO monad (in a purely functional manner) to create more complex I/O actions, resulting in the final I/O action that is the <code>main</code> value of the program.<br />
<br />
The standard prelude and the [http://www.haskell.org/onlinelibrary/io.html <code>IO</code> module] define many functions that can be used within the IO monad and any Haskell programmer will undoubtedly be familiar with some of them. This tutorial will only discuss the monadic aspects of the IO monad, not the full range of functions available to perform I/O.<br />
<br />
The <code>IO</code> type constructor is a member of the <code>Monad</code> class and the <code>MonadError</code> class, where errors are of the type <code>IOError</code>. <code>fail</code> is defined to throw an error built from the string argument. Within the <code>IO</code> monad you can use the exception mechanisms from the <code>Control.Monad.Error</code> module in the Monad Template Library if you import the module. The same mechanisms have alternative names exported by the <code>IO</code> module: <code>ioError</code> and <code>catch</code>.<br />
<br />
<haskell><br />
instance Monad IO where<br />
return a = ... -- function from a -> IO a<br />
m >>= k = ... -- executes the I/O action m and binds the value to k's input <br />
fail s = ioError (userError s)<br />
<br />
data IOError = ...<br />
<br />
ioError :: IOError -> IO a<br />
ioError = ...<br />
<br />
userError :: String -> IOError<br />
userError = ...<br />
<br />
catch :: IO a -> (IOError -> IO a) -> IO a <br />
catch = ...<br />
<br />
try :: IO a -> IO (Either IOError a)<br />
try f = catch (do r <- f<br />
return (Right r))<br />
(return . Left)<br />
</haskell><br />
The <code>IO</code> monad is incorporated into the Monad Template Library framework as an instance of the <code>MonadError</code> class.<br />
<br />
<haskell><br />
instance Error IOError where<br />
...<br />
<br />
instance MonadError IO where<br />
throwError = ioError<br />
catchError = catch<br />
</haskell><br />
The <code>IO</code> module exports a convenience function called <code>try</code> that executes an I/O action and returns <code>Right result</code> if the action succeeded or <code>Left IOError</code> if an I/O error was caught.<br />
<br />
== Example ==<br />
<br />
This example shows a partial implementation of the &quot;tr&quot; command that copies the standard input stream to the standard output stream with character translations controlled by command-line arguments. It demonstrates the use of the exception handling mechanisms of the <code>MonadError</code> class with the <code>IO</code> monad.<br />
<br />
Code available in [[../examples/example14.hs|example14.hs]]<br />
<br />
<haskell><br />
import Monad<br />
import System<br />
import IO<br />
import Control.Monad.Error<br />
<br />
-- translate char in set1 to corresponding char in set2<br />
translate :: String -> String -> Char -> Char<br />
translate [] _ c = c<br />
translate (x:xs) [] c = if x == c then ' ' else translate xs [] c<br />
translate (x:xs) [y] c = if x == c then y else translate xs [y] c<br />
translate (x:xs) (y:ys) c = if x == c then y else translate xs ys c<br />
<br />
-- translate an entire string<br />
translateString :: String -> String -> String -> String<br />
translateString set1 set2 str = map (translate set1 set2) str<br />
<br />
usage :: IOError -> IO ()<br />
usage e = do putStrLn "Usage: ex14 set1 set2"<br />
putStrLn "Translates characters in set1 on stdin to the corresponding"<br />
putStrLn "characters from set2 and writes the translation to stdout."<br />
<br />
-- translates stdin to stdout based on commandline arguments<br />
main :: IO ()<br />
main = (do [set1,set2] <- getArgs<br />
contents <- hGetContents stdin<br />
putStr $ translateString set1 set2 contents)<br />
`catchError` usage<br />
</haskell><br />
The State monad<br />
<br />
= The State monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which maintain state.<br />
<br />
Binding strategy:<br />
<br />
Binding threads a state parameter through the sequence of bound functions so that the same state value is never used twice, giving the illusion of in-place update.<br />
<br />
Useful for:<br />
<br />
Building computations from sequences of operations that require a shared state.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.State.html State st a]<br />
<br />
== Motivation ==<br />
<br />
A pure functional language cannot update values in place because it violates referential transparency. A common idiom to simulate such stateful computations is to &quot;thread&quot; a state parameter through a sequence of functions:<br />
<br />
<haskell><br />
data MyType = MT Int Bool Char Int deriving Show<br />
<br />
makeRandomValue :: StdGen -> (MyType, StdGen)<br />
makeRandomValue g = let (n,g1) = randomR (1,100) g<br />
(b,g2) = random g1<br />
(c,g3) = randomR ('a','z') g2 <br />
(m,g4) = randomR (-n,n) g3<br />
in (MT n b c m, g4)<br />
</haskell><br />
This approach works, but such code can be error-prone, messy and difficult to maintain. The State monad hides the threading of the state parameter inside the binding operation, simultaneously making the code easier to write, easier to read and easier to modify.<br />
<br />
== Definition ==<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 98. It is not necessary to fully understand these details to make use of the State monad.<br />
<br />
<haskell><br />
newtype State s a = State { runState :: (s -> (a,s)) } <br />
<br />
instance Monad (State s) where <br />
return a = State $ \s -> (a,s)<br />
(State x) >>= f = State $ \s -> let (v,s') = x s in runState (f v) s' <br />
</haskell><br />
Values in the State monad are represented as transition functions from an initial state to a (value,newState) pair and a new type definition is provided to describe this construct: <code>State s a</code> is the type of a value of type <code>a</code> inside the State monad with state of type <code>s</code>.<br />
<br />
The type constructor <code>State s</code> is an instance of the <code>Monad</code> class. The <code>return</code> function simply creates a state transition function which sets the value but leaves the state unchanged. The binding operator creates a state transition function that applies its right-hand argument to the value and new state from its left-hand argument.<br />
<br />
<haskell><br />
class MonadState m s | m -> s where <br />
get :: m s<br />
put :: s -> m ()<br />
<br />
instance MonadState (State s) s where <br />
get = State $ \s -> (s,s) <br />
put s = State $ \_ -> ((),s) <br />
</haskell><br />
The <code>MonadState</code> class provides a standard but very simple interface for State monads. The <code>get</code> function retrieves the state by copying it as the value. The <code>put</code> function sets the state of the monad and does not yield a value.<br />
<br />
There are many additional functions provide which perform more complex computations built on top of <code>get</code> and put. The most useful one is <code>gets</code> which retrieves a function of the state. The others are listed in the [http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.State.html documentation] for the State monad library.<br />
<br />
== Example ==<br />
<br />
A simple application of the State monad is to thread the random generator state through multiple calls to the generation function.<br />
<br />
Code available in [[../examples/example15.hs|example15.hs]]<br />
<br />
<haskell><br />
data MyType = MT Int Bool Char Int deriving Show<br />
<br />
{- Using the State monad, we can define a function that returns<br />
a random value and updates the random generator state at<br />
the same time.<br />
-}<br />
getAny :: (Random a) => State StdGen a<br />
getAny = do g <- get<br />
(x,g') <- return $ random g<br />
put g'<br />
return x<br />
<br />
-- similar to getAny, but it bounds the random value returned<br />
getOne :: (Random a) => (a,a) -> State StdGen a<br />
getOne bounds = do g <- get<br />
(x,g') <- return $ randomR bounds g<br />
put g'<br />
return x<br />
<br />
{- Using the State monad with StdGen as the state, we can build<br />
random complex types without manually threading the<br />
random generator states through the code.<br />
-} <br />
makeRandomValueST :: StdGen -> (MyType, StdGen)<br />
makeRandomValueST = runState (do n <- getOne (1,100)<br />
b <- getAny<br />
c <- getOne ('a','z')<br />
m <- getOne (-n,n)<br />
return (MT n b c m))<br />
</haskell><br />
The Reader monad<br />
<br />
= The Reader monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which read values from a shared environment.<br />
<br />
Binding strategy:<br />
<br />
Monad values are functions from the environment to a value. The bound function is applied to the bound value, and both have access to the shared environment.<br />
<br />
Useful for:<br />
<br />
Maintaining variable bindings, or other shared environment.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Reader.html Reader [(String,Value)] a]<br />
<br />
== Motivation ==<br />
<br />
Some programming problems require computations within a shared environment (such as a set of variable bindings). These computations typically read values from the environment and sometimes execute sub-computations in a modified environment (with new or shadowing bindings, for example), but they do not require the full generality of the State monad.<br />
<br />
The Reader monad is specifically designed for these types of computations and is often a clearer and easier mechanism than using the State monad.<br />
<br />
== Definition ==<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 98. It is not necessary to fully understand these details to make use of the Reader monad.<br />
<br />
<haskell><br />
newtype Reader e a = Reader { runReader :: (e -> a) }<br />
<br />
instance Monad (Reader e) where <br />
return a = Reader $ \e -> a <br />
(Reader r) >>= f = Reader $ \e -> runReader (f (r e)) e <br />
</haskell><br />
Values in the Reader monad are functions from an environment to a value. To extract the final value from a computation in the Reader monad, you simply apply <code>(runReader reader)</code> to an environment value.<br />
<br />
The <code>return</code> function creates a <code>Reader</code> that ignores the environment and produces the given value. The binding operator produces a <code>Reader</code> that uses the environment to extract the value its left-hand side and then applies the bound function to that value in the same environment.<br />
<br />
<haskell><br />
class MonadReader e m | m -> e where <br />
ask :: m e<br />
local :: (e -> e) -> m a -> m a <br />
<br />
instance MonadReader (Reader e) where <br />
ask = Reader id <br />
local f c = Reader $ \e -> runReader c (f e) <br />
<br />
asks :: (MonadReader e m) => (e -> a) -> m a <br />
asks sel = ask >>= return . sel<br />
</haskell><br />
The <code>MonadReader</code> class provides a number of convenience functions that are very useful when working with a Reader monad. The <code>ask</code> function retrieves the environment and the <code>local</code> function executes a computation in a modified environment. The <code>asks</code> function is a convenience function that retrieves a function of the current environment, and is typically used with a selector or lookup function.<br />
<br />
== Example ==<br />
<br />
Consider the problem of instantiating templates which contain variable substitutions and included templates. Using the Reader monad, we can maintain an environment of all known templates and all known variable bindings. Then, when a variable substitution is encountered, we can use the <code>asks</code> function to lookup the value of the variable. When a template is included with new variable definitions, we can use the <code>local</code> function to resolve the template in a modified environment that contains the additional variable bindings.<br />
<br />
Code available in [[../examples/example16.hs|example16.hs]]<br />
<br />
<haskell><br />
-- This the abstract syntax representation of a template<br />
-- Text Variable Quote Include Compound<br />
data Template = T String | V Template | Q Template | I Template [Definition] | C [Template]<br />
data Definition = D Template Template<br />
<br />
-- Our environment consists of an association list of named templates and<br />
-- an association list of named variable values. <br />
data Environment = Env {templates::[(String,Template)],<br />
variables::[(String,String)]}<br />
<br />
-- lookup a variable from the environment<br />
lookupVar :: String -> Environment -> Maybe String<br />
lookupVar name env = lookup name (variables env)<br />
<br />
-- lookup a template from the environment<br />
lookupTemplate :: String -> Environment -> Maybe Template<br />
lookupTemplate name env = lookup name (templates env)<br />
<br />
-- add a list of resolved definitions to the environment<br />
addDefs :: [(String,String)] -> Environment -> Environment<br />
addDefs defs env = env {variables = defs ++ (variables env)}<br />
<br />
-- resolve a Definition and produce a (name,value) pair<br />
resolveDef :: Definition -> Reader Environment (String,String)<br />
resolveDef (D t d) = do name <- resolve t<br />
value <- resolve d<br />
return (name,value)<br />
<br />
-- resolve a template into a string<br />
resolve :: Template -> Reader Environment (String)<br />
resolve (T s) = return s<br />
resolve (V t) = do varName <- resolve t<br />
varValue <- asks (lookupVar varName)<br />
return $ maybe "" id varValue<br />
resolve (Q t) = do tmplName <- resolve t<br />
body <- asks (lookupTemplate tmplName)<br />
return $ maybe "" show body <br />
resolve (I t ds) = do tmplName <- resolve t<br />
body <- asks (lookupTemplate tmplName)<br />
case body of<br />
Just t' -> do defs <- mapM resolveDef ds<br />
local (addDefs defs) (resolve t')<br />
Nothing -> return ""<br />
resolve (C ts) = (liftM concat) (mapM resolve ts)<br />
</haskell><br />
To use the Reader monad to resolve a template <code>t</code> into a <code>String</code>, you simply need to do <code>runReader (resolve t) env</code>.<br />
<br />
The Writer monad<br />
<br />
= The Writer monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which produce a stream of data in addition to the computed values.<br />
<br />
Binding strategy:<br />
<br />
A Writer monad value is a (computation value, log value) pair. Binding replaces the computation value with the result of applying the bound function to the previous value and appends any log data from the computation to the existing log data.<br />
<br />
Useful for:<br />
<br />
Logging, or other computations that produce output &quot;on the side&quot;.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Writer.html Writer [String] a]<br />
<br />
== Motivation ==<br />
<br />
It is often desirable for a computation to generate output &quot;on the side&quot;. Logging and tracing are the most common examples in which data is generated during a computation that we want to retain but is not the primary result of the computation.<br />
<br />
Explicitly managing the logging or tracing data can clutter up the code and invite subtle bugs such as missed log entries. The Writer monad provides a cleaner way to manage the output without cluttering the main computation.<br />
<br />
== Definition ==<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 98. It is not necessary to fully understand these details to make use of the Writer monad.<br />
<br />
[[Image:info.png]] To fully understand this definition, you need to know about Haskell's <code>Monoid</code> class, which represents a mathematical structure called a monoid in the same way that the <code>Monad</code> class represents the monad structure.<br />
<br />
The good news is that monoids are simpler than monads. A monoid is a set of objects, a single identity element, and an associative binary operator over the set of objects. A monoid must obey some mathematical laws, such that applying the operator to any values from the set gives another value in the set, and whenever one operand of the operator is the identity element the result is equal to the other operand. You may notice that these laws are the same as the laws governing <code>mzero</code> and <code>mplus</code> for instances of <code>MonadPlus</code>. That is because monads with a zero and plus are monads that are also monoids!<br />
<br />
Some examples of mathematical monoids are the natural numbers with identity element 0 and binary operator for addition, and also the natural numbers with identity element 1 and binary operator for multiplication.<br />
<br />
In Haskell, a monoid consists of a type, an identity element, and a binary operator. Haskell defines the <code>Monoid</code> class (in Data.Monoid) to provide a standard convention for working with monoids: the identity element is named <code>mempty</code> and the operator is named <code>mappend</code>.<br />
<br />
The most commonly used standard monoid in Haskell is the list, but functions of type <code>(a -> a)</code> also form a monoid.<br />
<br />
[[Image:warn.png]] Care should be taken when using a list as the monoid for a Writer, as there may be a performance penalty associated with the <code>mappend</code> operation as the output grows. In that case, a data structure that supports fast append operations would be a more appropriate choice.<br />
<br />
<haskell><br />
newtype Writer w a = Writer { runWriter :: (a,w) } <br />
<br />
instance (Monoid w) => Monad (Writer w) where <br />
return a = Writer (a,mempty) <br />
(Writer (a,w)) >>= f = let (a',w') = runWriter $ f a in Writer (a',w `mappend` w')<br />
</haskell><br />
The Writer monad maintains a (value,log) pair, where the log type must be a monoid. The <code>return</code> function simply returns the value along with an empty log. Binding executes the bound function using the current value as input, and appends any log output to the existing log.<br />
<br />
<haskell><br />
class (Monoid w, Monad m) => MonadWriter w m | m -> w where <br />
pass :: m (a,w -> w) -> m a <br />
listen :: m a -> m (a,w) <br />
tell :: w -> m () <br />
<br />
instance (Monoid w) => MonadWriter (Writer w) where <br />
pass (Writer ((a,f),w)) = Writer (a,f w) <br />
listen (Writer (a,w)) = Writer ((a,w),w) <br />
tell s = Writer ((),s) <br />
<br />
listens :: (MonadWriter w m) => (w -> b) -> m a -> m (a,b)<br />
listens f m = do (a,w) <- listen m; return (a,f w)<br />
<br />
censor :: (MonadWriter w m) => (w -> w) -> m a -> m a <br />
censor f m = pass $ do a <- m; return (a,f)<br />
</haskell><br />
The <code>MonadWriter</code> class provides a number of convenience functions for working with Writer monads. The simplest and most useful is <code>tell</code>, which adds one or more entries to the log. The <code>listen</code> function turns a Writer that returns a value <code>a</code> and produces output <code>w</code> into a Writer that produces a value <code>(a,w)</code> and still produces output <code>w</code>. This allows the computation to &quot;listen&quot; to the log output generated by a Writer.<br />
<br />
The <code>pass</code> function is slightly more complicated. It converts a Writer that produces a value <code>(a,f)</code> and output <code>w</code> into a Writer that produces a value <code>a</code> and output <code>f w</code>. This is somewhat cumbersome, so the helper function <code>censor</code> is normally used. The <code>censor</code> function takes a function and a Writer and produces a new Writer whose output is the same but whose log entry has been modified by the function.<br />
<br />
The <code>listens</code> function operates just like <code>listen</code> except that the log part of the value is modified by the supplied function.<br />
<br />
== Example ==<br />
<br />
In this example, we imagine a very simple firewall that filters packets based on a rulebase of rules matching the source and destination hosts and the payload of the packet. The firewall's primary job is packet filtering, but we would also like it to produce a log of its activity.<br />
<br />
Code available in [[../examples/example17.hs|example17.hs]]<br />
<br />
<haskell><br />
-- this is the format of our log entries<br />
data Entry = Log {count::Int, msg::String} deriving Eq<br />
<br />
-- add a message to the log<br />
logMsg :: String -> Writer [Entry] ()<br />
logMsg s = tell [Log 1 s]<br />
<br />
-- this handles one packet<br />
filterOne :: [Rule] -> Packet -> Writer [Entry] (Maybe Packet)<br />
filterOne rules packet = do <br />
rule <- return (match rules packet)<br />
case rule of<br />
Nothing -> do<br />
logMsg $ "DROPPING UNMATCHED PACKET: " ++ (show packet)<br />
return Nothing<br />
(Just r) -> do<br />
when (logIt r) $ logMsg ("MATCH: " ++ (show r) ++ " <=> " ++ (show packet))<br />
case r of (Rule Accept _ _) -> return $ Just packet<br />
(Rule Reject _ _) -> return Nothing<br />
</haskell><br />
That was pretty simple, but what if we want to merge duplicate consecutive log entries? None of the existing functions allow us to modify the output from previous stages of the computation, but we can use a &quot;delayed logging&quot; trick to only add a log entry only after we get a new entry that doesn't match the ones before it.<br />
<br />
Code available in [[../examples/example17.hs|example17.hs]]<br />
<br />
<haskell><br />
-- merge identical entries at the end of the log<br />
-- This function uses [Entry] as both the log type and the result type.<br />
-- When two identical messages are merged, the result is just the message<br />
-- with an incremented count. When two different messages are merged,<br />
-- the first message is logged and the second is returned as the result.<br />
mergeEntries :: [Entry] -> [Entry] -> Writer [Entry] [Entry]<br />
mergeEntries [] x = return x<br />
mergeEntries x [] = return x<br />
mergeEntries [e1] [e2] = let (Log n msg) = e1<br />
(Log n' msg') = e2<br />
in if msg == msg' then<br />
return [(Log (n+n') msg)]<br />
else<br />
do tell [e1]<br />
return [e2]<br />
<br />
-- This is a complex-looking function but it is actually pretty simple.<br />
-- It maps a function over a list of values to get a list of Writers,<br />
-- then runs each writer and combines the results. The result of the function<br />
-- is a writer whose value is a list of all the values from the writers and whose<br />
-- log output is the result of folding the merge operator into the individual<br />
-- log entries (using 'initial' as the initial log value).<br />
groupSame :: (Monoid a) => a -> (a -> a -> Writer a a) -> [b] -> (b -> Writer a c) -> Writer a [c]<br />
groupSame initial merge [] _ = do tell initial<br />
return []<br />
groupSame initial merge (x:xs) fn = do (result,output) <- return (runWriter (fn x))<br />
new <- merge initial output<br />
rest <- groupSame new merge xs fn<br />
return (result:rest)<br />
<br />
-- this filters a list of packets, producing a filtered packet list and a log of<br />
-- the activity in which consecutive messages are merged<br />
filterAll :: [Rule] -> [Packet] -> Writer [Entry] [Packet]<br />
filterAll rules packets = do tell [Log 1 "STARTING PACKET FILTER"]<br />
out <- groupSame [] mergeEntries packets (filterOne rules)<br />
tell [Log 1 "STOPPING PACKET FILTER"]<br />
return (catMaybes out)<br />
</haskell><br />
The Continuation monad<br />
<br />
= The Continuation monad =<br />
<br />
== Overview ==<br />
<br />
Computation type:<br />
<br />
Computations which can be interrupted and resumed.<br />
<br />
Binding strategy:<br />
<br />
Binding a function to a monadic value creates a new continuation which uses the function as the continuation of the monadic computation.<br />
<br />
Useful for:<br />
<br />
Complex control structures, error handling and creating co-routines.<br />
<br />
Zero and plus:<br />
<br />
None.<br />
<br />
Example type:<br />
<br />
[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Cont.html Cont r a]<br />
<br />
== Motivation ==<br />
<br />
[[Image:warn.png]] Abuse of the Continuation monad can produce code that is impossible to understand and maintain.<br />
<br />
Before using the Continuation monad, be sure that you have a firm understanding of continuation-passing style (CPS) and that continuations represent the best solution to your particular design problem. Many algorithms which require continuations in other languages do not require them in Haskell, due to Haskell's lazy semantics.<br />
<br />
Continuations represent the ''future'' of a computation, as a function from an intermediate result to the final result. In continuation-passing style, computations are built up from sequences of nested continuations, terminated by a final continuation (often <code>id</code>) which produces the final result. Since continuations are functions which represent the future of a computation, manipulation of the continuation functions can achieve complex manipulations of the future of the computation, such as interrupting a computation in the middle, aborting a portion of a computation, restarting a computation and interleaving execution of computations. The Continuation monad adapts CPS to the structure of a monad.<br />
<br />
== Definition ==<br />
<br />
<haskell><br />
newtype Cont r a = Cont { runCont :: ((a -> r) -> r) } -- r is the final result type of the whole computation <br />
<br />
instance Monad (Cont r) where <br />
return a = Cont $ \k -> k a -- i.e. return a = \k -> k a <br />
(Cont c) >>= f = Cont $ \k -> c (\a -> runCont (f a) k) -- i.e. c >>= f = \k -> c (\a -> f a k) <br />
</haskell><br />
The Continuation monad represents computations in continuation-passing style. <code>Cont r a</code> is a CPS computation that produces an intermediate result of type <code>a</code> within a CPS computation whose final result type is <code>r</code>.<br />
<br />
The <code>return</code> function simply creates a continuation which passes the value on. The <code>>>=</code> operator adds the bound function into the continuation chain.<br />
<br />
<haskell><br />
class (Monad m) => MonadCont m where <br />
callCC :: ((a -> m b) -> m a) -> m a <br />
<br />
instance MonadCont (Cont r) where <br />
callCC f = Cont $ \k -> runCont (f (\a -> Cont $ \_ -> k a)) k<br />
</haskell><br />
The <code>MonadCont</code> class provides the <code>callCC</code> function, which provides an escape continuation mechanism for use with Continuation monads. Escape continuations allow you to abort the current computation and return a value immediately. They achieve a similar effect to <code>throwError</code> and catchError within an <code>Error</code> monad.<br />
<br />
<code>callCC</code> calls a function with the current continuation as its argument (hence the name). The standard idiom used with <code>callCC</code> is to provide a lambda-expression to name the continuation. Then calling the named continuation anywhere within its scope will escape from the computation, even if it is many layers deep within nested computations.<br />
<br />
In addition to the escape mechanism provided by <code>callCC</code>, the Continuation monad can be used to implement other, more powerful continuation manipulations. These other mechanisms have fairly specialized uses, however — and abuse of them can easily create fiendishly obfuscated code — so they will not be covered here.<br />
<br />
== Example ==<br />
<br />
This example gives a taste of how escape continuations work. The example function uses escape continuations to perform a complicated transformation on an integer.<br />
<br />
Code available in [[../examples/example18.hs|example18.hs]]<br />
<br />
<haskell><br />
{- We use the continuation monad to perform "escapes" from code blocks.<br />
This function implements a complicated control structure to process<br />
numbers:<br />
<br />
Input (n) Output List Shown<br />
========= ====== ==========<br />
0-9 n none<br />
10-199 number of digits in (n/2) digits of (n/2)<br />
200-19999 n digits of (n/2)<br />
20000-1999999 (n/2) backwards none<br />
>= 2000000 sum of digits of (n/2) digits of (n/2)<br />
-} <br />
fun :: Int -> String<br />
fun n = (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do -- define "exit1"<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- define "exit2"<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns') --escape 2 levels<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
Part III - Introduction<br />
<br />
= Introduction =<br />
<br />
Part I has introduced the monad concept and Part II has provided an understanding of a number of common, useful monads in the standard Haskell libraries. This is not enough to put monads into heavy practice, however, because in the real world you often want computations which combine aspects of more than one monad at the same time, such as stateful, non-determistic computations or computations which make use of continuations and perform I/O. When one computation is a strict subset of the other, it is possible to perform the monad computations separately, unless the sub-computation is performed in a one-way monad.<br />
<br />
Often, the computations can't be performed in isolation. In this case, what is needed is a monad that combines the features of the two monads into a single computation. It is inefficient and poor practice to write a new monad instance with the required characteristics each time a new combination is desired. Instead, we would prefer to develop a way to combine the standard monads to produce the needed hybrids. The technique that lets us do exactly that is called monad transformers.<br />
<br />
Monad transformers are the topic of Part III, and they are explained by revisiting earlier examples to see how monad transformers can be used to add more realistic capabilities to them. It may be helpful to review the earlier examples as they are re-examined.<br />
<br />
Combining monads the hard way<br />
<br />
= Combining monads the hard way =<br />
<br />
Before we investigate the use of monad transformers, we will see how monads can be combined without using transformers. This is a useful excercise to develop insights into the issues that arise when combining monads and provides a baseline from which the advantages of the transformer approach can be measured. We use the code from [[contmonad.html#example|example 18]] (the Continuation monad) to illustrate these issues, so you may want to review it before continuing.<br />
<br />
== Nested Monads ==<br />
<br />
Some computations have a simple enough structure that the monadic computations can be nested, avoiding the need for a combined monad altogether. In Haskell, all computations occur in the IO monad at the top level, so the monad examples we have seen so far all actually use the technique of nested monadic computations. To do this, the computations perform all of their input at the beginning — usually by reading arguments from the command line — then pass the values on to the monadic computations to produce results, and finally perform their output at the end. This structure avoids the issues of combining monads but makes the examples seem contrived at times.<br />
<br />
The code introduced in example 18 followed the nesting pattern: reading a number from the command line in the IO monad, passing that number to a computation in the Continuation monad to produce a string, and then writing the string back in the IO monad. The computations in the IO monad aren't restricted to reading from the command line and writing strings; they can be arbitrarily complex. Likewise, the inner computation can be arbitrarily complex as well. As long as the inner computation does not depend on the functionality of the outer monad, it can be safely nested within the outer monad, as illustrated in this variation on example 18 which reads the value from stdin instead of using a command line argument:<br />
<br />
Code available in [[../examples/example19.hs|example19.hs]]<br />
<br />
<haskell><br />
fun :: IO String<br />
fun = do n <- (readLn::IO Int) -- this is an IO monad block<br />
return $ (`runCont` id) $ do -- this is a Cont monad block<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
== Combined Monads ==<br />
<br />
What about computations with more complicated structure? If the nesting pattern cannot be used, we need a way to combine the attributes of two or more monads in a single computation. This is accomplished by doing computations within a monad in which the values are themselves monadic values in another monad. For example, we might perform computations in the Continuation monad of type <code>Cont (IO String) a</code> if we need to perform I/O within the computation in the Continuation monad. We could use a monad of type <code>State (Either Err a) a</code> to combine the features of the State and Error monads in a single computation.<br />
<br />
Consider a slight modification to our example in which we perform the same I/O at the beginning, but we may require additional input in the middle of the computation in the Continuation monad. In this case, we will allow the user to specify part of the output value when the input value is within a certain range. Because the I/O depends on part of the computation in the Continuation monad and part of the computation in the Continuation monad depends on the result of the I/O, we cannot use the nested monad pattern.<br />
<br />
Instead, we make the computation in the Continuation monad use values from the IO monad. What used to be <code>Int</code> and <code>String</code> values are now of type <code>IO Int</code> and <code>IO String</code>. We can't extract values from the IO monad — it's a one-way monad — so we may need to nest little do-blocks of the IO monad within the Continuation monad to manipulate the values. We use a helper function <code>toIO</code> to make it clearer when we are creating values in the IO monad nested within the Continuation monad.<br />
<br />
Code available in [[../examples/example20.hs|example20.hs]]<br />
<br />
<haskell><br />
toIO :: a -> IO a<br />
toIO x = return x<br />
<br />
fun :: IO String<br />
fun = do n <- (readLn::IO Int) -- this is an IO monad block<br />
convert n<br />
<br />
convert :: Int -> IO String<br />
convert n = (`runCont` id) $ do -- this is a Cont monad block<br />
str <- callCC $ \exit1 -> do -- str has type IO String<br />
when (n < 10) (exit1 $ toIO (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- n' has type IO Int<br />
when ((length ns) < 3) (exit2 (toIO (length ns)))<br />
when ((length ns) < 5) (exit2 $ do putStrLn "Enter a number:"<br />
x <- (readLn::IO Int)<br />
return x)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 $ toIO (dropWhile (=='0') ns')<br />
return (toIO (sum ns))<br />
return $ do num <- n' -- this is an IO monad block<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show num)<br />
return $ do s <- str -- this is an IO monad block<br />
return $ "Answer: " ++ s<br />
</haskell><br />
Even this trivial example has gotten confusing and ugly when we tried to combine different monads in the same computation. It works, but it isn't pretty. Comparing the code side-by-side shows the degree to which the manual monad combination strategy pollutes the code.<br />
<br />
Nested monads from example 19<br />
<br />
Manually combined monads from example 20<br />
<br />
<haskell><br />
fun = do n <- (readLn::IO Int)<br />
return $ (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<haskell><br />
convert n = (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 $ toIO (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (toIO (length ns)))<br />
when ((length ns) < 5) (exit2 $ do<br />
putStrLn "Enter a number:"<br />
x <- (readLn::IO Int)<br />
return x)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 $ toIO (dropWhile (=='0') ns')<br />
return (toIO (sum ns))<br />
return $ do num <- n'<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show num)<br />
return $ do s <- str<br />
return $ "Answer: " ++ s<br />
</haskell><br />
Monad transformers<br />
<br />
= Monad transformers =<br />
<br />
Monad transformers are special variants of standard monads that facilitate the combining of monads. Their type constructors are parameterized over a monad type constructor, and they produce combined monadic types.<br />
<br />
== Transformer type constructors ==<br />
<br />
Type constructors play a fundamental role in Haskell's monad support. Recall that <code>Reader r a</code> is the type of values of type <code>a</code> within a Reader monad with environment of type <code>r</code>. The type constructor <code>Reader r</code> is an instance of the <code>Monad</code> class, and the <code>runReader::(r->a)</code> function performs a computation in the Reader monad and returns the result of type <code>a</code>.<br />
<br />
A transformer version of the Reader monad, called <code>ReaderT</code>, exists which adds a monad type constructor as an addition parameter. <code>ReaderT r m a</code> is the type of values of the combined monad in which Reader is the base monad and <code>m</code> is the inner monad. <code>ReaderT r m</code> is an instance of the monad class, and the <code>runReaderT::(r -> m a)</code> function performs a computation in the combined monad and returns a result of type <code>m a</code>.<br />
<br />
Using the transformer versions of the monads, we can produce combined monads very simply. <code>ReaderT r IO</code> is a combined Reader+IO monad. We can also generate the non-transformer version of a monad from the transformer version by applying it to the Identity monad. So <code>ReaderT r Identity</code> is the same monad as <code>Reader r</code>.<br />
<br />
[[Image:info.png]] If your code produces kind errors during compilation, it means that you are not using the type cosntructors properly. Make sure that you have supplied the correct number of parameters to the type constructors and that you have not left out any parenthesis in complex type expressions.<br />
<br />
== Lifting ==<br />
<br />
When using combined monads created by the monad transformers, we avoid having to explicitly manage the inner monad types, resulting in clearer, simpler code. Instead of creating additional do-blocks within the computation to manipulate values in the inner monad type, we can use lifting operations to bring functions from the inner monad into the combined monad.<br />
<br />
Recall the <code>liftM</code> family of functions which are used to lift non-monadic functions into a monad. Each monad transformer provides a <code>lift</code> function that is used to lift a monadic computation into a combined monad. Many transformers also provide a <code>liftIO</code> function, which is a version of <code>lift</code> that is optimized for lifting computations in the <code>IO</code> monad. To see this in action, we will continue to develop our previous example in the Continuation monad.<br />
<br />
Code available in [[../examples/example21.hs|example21.hs]]<br />
<br />
<haskell><br />
fun :: IO String<br />
fun = (`runContT` return) $ do<br />
n <- liftIO (readLn::IO Int)<br />
str <- callCC $ \exit1 -> do -- define "exit1"<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- define "exit2"<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) $ do liftIO $ putStrLn "Enter a number:"<br />
x <- liftIO (readLn::IO Int)<br />
exit2 x<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns') --escape 2 levels<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
Compare this function using <code>ContT</code>, the transformer version of <code>Cont</code>, with the original version to see how unobtrusive the changes become when using the monad transformer.<br />
<br />
Nested monads from example 19<br />
<br />
Monads combined with a transformer from example 21<br />
<br />
<haskell><br />
fun = do n <- (readLn::IO Int)<br />
return $ (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<haskell><br />
fun = (`runContT` return) $ do<br />
n <- liftIO (readLn::IO Int)<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) $ do<br />
liftIO $ putStrLn "Enter a number:"<br />
x <- liftIO (readLn::IO Int)<br />
exit2 x<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
The impact of adding the I/O in the middle of the computation is narrowly confined when using the monad transformer. Contrast this with the [[hardway.html#comparison|changes]] required to achieve the same result using a manually combined monad.<br />
<br />
Standard monad transformers<br />
<br />
= Standard monad transformers =<br />
<br />
Haskell's base libraries provide support for monad transformers in the form of classes which represent monad transformers and special transformer versions of standard monads.<br />
<br />
== The MonadTrans and MonadIO classes ==<br />
<br />
The <code>MonadTrans</code> class is defined in [http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Trans.html Control.Monad.Trans] and provides the single function <code>lift</code>. The <code>lift</code> function lifts a monadic computation in the inner monad into the combined monad.<br />
<br />
<haskell><br />
class MonadTrans t where<br />
lift :: (Monad m) => m a -> t m a<br />
</haskell><br />
Monads which provide optimized support for lifting IO operations are defined as members of the <code>MonadIO</code> class, which defines the <code>liftIO</code> function.<br />
<br />
<haskell><br />
class (Monad m) => MonadIO m where<br />
liftIO :: IO a -> m a<br />
</haskell><br />
== Transformer versions of standard monads ==<br />
<br />
The standard monads of the monad template library all have transformer versions which are defined consistently with their non-transformer versions. However, it is not the case the all monad transformers apply the same transformation. We have seen that the <code>ContT</code> transformer turns continuations of the form <code>(a->r)->r</code> into continuations of the form <code>(a->m r)->m r</code>. The <code>StateT</code> transformer is different. It turns state transformer functions of the form <code>s->(a,s)</code> into state transformer functions of the form <code>s->m (a,s)</code>. In general, there is no magic formula to create a transformer version of a monad — the form of each transformer depends on what makes sense in the context of its non-transformer type.<br />
<br />
<table><br />
<tr class="header"><br />
<th align="left">Standard Monad</th><br />
<th align="left">Transformer Version</th><br />
<th align="left">Original Type</th><br />
<th align="left">Combined Type</th><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[errormonad.html|Error]]</td><br />
<td align="left">[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Error.html#ErrorT ErrorT]</td><br />
<td align="left"><code>Either e a</code></td><br />
<td align="left"><code>m (Either e a)</code></td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[statemonad.html|State]]</td><br />
<td align="left">[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.State.html#StateT StateT]</td><br />
<td align="left"><code>s -> (a,s)</code></td><br />
<td align="left"><code>s -> m (a,s)</code></td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[readermonad.html|Reader]]</td><br />
<td align="left">[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Reader.html#ReaderT ReaderT]</td><br />
<td align="left"><code>r -> a</code></td><br />
<td align="left"><code>r -> m a</code></td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[writermonad.html|Writer]]</td><br />
<td align="left">[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Writer.html#WriterT WriterT]</td><br />
<td align="left"><code>(a,w)</code></td><br />
<td align="left"><code>m (a,w)</code></td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[contmonad.html|Cont]]</td><br />
<td align="left">[http://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Cont.html#ContT ContT]</td><br />
<td align="left"><code>(a -> r) -> r</code></td><br />
<td align="left"><code>(a -> m r) -> m r</code></td><br />
</tr><br />
</table><br />
<br />
[[Image:info.png]] Order is important when combining monads. <code>StateT s (Error e)</code> is different than <code>ErrorT e (State s)</code>. The first produces a combined type of <code>s -> Error e (a,s)</code>, in which the computation can either return a new state or generate an error. The second combination produces a combined type of <code>s -> (Error e a,s)</code>, in which the computation always returns a new state, and the value can be an error or a normal value.<br /><br />
<br />
<br />
Anatomy of a monad transformer<br />
<br />
= Anatomy of a monad transformer =<br />
<br />
In this section, we will take a detailed look at the implementation of one of the more interesting transformers in the standard library, <code>StateT</code>. Studying this transformer will build insight into the transformer mechanism that you can call upon when using monad transformers in your code. You might want to review the section on the [[statemonad.html|State monad]] before continuing.<br />
<br />
== Combined monad definition ==<br />
<br />
Just as the State monad was built upon the definition<br />
<br />
<haskell><br />
newtype State s a = State { runState :: (s -> (a,s)) }<br />
</haskell><br />
the StateT transformer is built upon the definition<br />
<br />
<haskell><br />
newtype StateT s m a = StateT { runStateT :: (s -> m (a,s)) }<br />
</haskell><br />
<code>State s</code> is an instance of both the <code>Monad</code> class and the <code>MonadState s</code> class, so <code>StateT s m</code> should also be members of the <code>Monad</code> and <code>MonadState s</code> classes. Furthermore, if <code>m</code> is an instance of <code>MonadPlus</code>, <code>StateT s m</code> should also be a member of <code>MonadPlus</code>.<br />
<br />
To define <code>StateT s m</code> as a <code>Monad</code> instance:<br />
<br />
<haskell><br />
newtype StateT s m a = StateT { runStateT :: (s -> m (a,s)) }<br />
<br />
instance (Monad m) => Monad (StateT s m) where<br />
return a = StateT $ \s -> return (a,s)<br />
(StateT x) >>= f = StateT $ \s -> do (v,s') <- x s -- get new value, state<br />
(StateT x') <- return $ f v -- apply bound function to get new state transformation fn<br />
x' s' -- apply the state transformation fn to the new state<br />
</haskell><br />
Compare this to the definition for [[statemonad.html#definition|<code>State s</code>]]. Our definition of <code>return</code> makes use of the <code>return</code> function of the inner monad, and the binding operator uses a do-block to perform a computation in the inner monad.<br />
<br />
We also want to declare all combined monads that use the <code>StateT</code> transformer to be instaces of the <code>MonadState</code> class, so we will have to give definitions for <code>get</code> and <code>put</code>:<br />
<br />
<haskell><br />
instance (Monad m) => MonadState s (StateT s m) where<br />
get = StateT $ \s -> return (s,s)<br />
put s = StateT $ \_ -> return ((),s)<br />
</haskell><br />
Finally, we want to declare all combined monads in which <code>StateT</code> is used with an instance of <code>MonadPlus</code> to be instances of <code>MonadPlus</code>:<br />
<br />
<haskell><br />
instance (MonadPlus m) => MonadPlus (StateT s m) where<br />
mzero = StateT $ \s -> mzero<br />
(StateT x1) `mplus` (StateT x2) = StateT $ \s -> (x1 s) `mplus` (x2 s)<br />
</haskell><br />
== Defining the lifting function ==<br />
<br />
The final step to make our monad transformer fully integrated with Haskell's monad classes is to make <code>StateT s</code> an instance of the <code>MonadTrans</code> class by providing a <code>lift</code> function:<br />
<br />
<haskell><br />
instance MonadTrans (StateT s) where<br />
lift c = StateT $ \s -> c >>= (\x -> return (x,s))<br />
</haskell><br />
The <code>lift</code> function creates a <code>StateT</code> state transformation function that binds the computation in the inner monad to a function that packages the result with the input state. The result is that a function that returns a list (i.e., a computation in the List monad) can be lifted into <code>StateT s []</code>, where it becomes a function that returns a <code>StateT (s -> [(a,s)])</code>. That is, the lifted computation produces ''multiple'' (value,state) pairs from its input state. The effect of this is to &quot;fork&quot; the computation in StateT, creating a different branch of the computation for each value in the list returned by the lifted function. Of course, applying <code>StateT</code> to a different monad will produce different semantics for the <code>lift</code> function.<br />
<br />
== Functors ==<br />
<br />
We have examined the implementation of one monad transformer above, and it was stated earlier that there was no magic formula to produce transformer versions of monads. Each transformer's implementation will depend on the nature of the computational effects it is adding to the inner monad.<br />
<br />
Despite this, there is some theoretical foundation to the theory of monad transformers. Certain transformers can be grouped according to how they use the inner monad, and the transformers within each group can be derived using monadic functions and functors. Functors, roughly, are types which support a mapping operation <code>fmap :: (a->b) -> f a -> f b</code>. To learn more about it, check out Mark Jones' influential [http://www-internal.cse.ogi.edu/~mpj/pubs/springschool95.ps paper] that inspired the Haskell monad template library.<br />
<br />
More examples with monad transformers<br />
<br />
= More examples with monad transformers =<br />
<br />
At this point, you should know everything you need to begin using monads and monad transformers in your programs. The best way to build proficiency is to work on actual code. As your monadic programs become more abitious, you may find it awkward to mix additional transformers into your combined monads. This will be addressed in the next section, but first you should master the basic process of applying a single transformer to a base monad.<br />
<br />
== WriterT with IO ==<br />
<br />
Try adapting the [[writermonad.html#example|firewall simulator]] of example 17 to include a timestamp on each log entry (don't worry about merging entries). The necessary changes should look something like this:<br />
<br />
Code available in [[../examples/example22.hs|example22.hs]]<br />
<br />
<haskell><br />
-- this is the format of our log entries<br />
data Entry = Log {timestamp::ClockTime, msg::String} deriving Eq<br />
<br />
instance Show Entry where<br />
show (Log t s) = (show t) ++ " | " ++ s<br />
<br />
-- this is the combined monad type<br />
type LogWriter a = WriterT [Entry] IO a<br />
<br />
-- add a message to the log<br />
logMsg :: String -> LogWriter ()<br />
logMsg s = do t <- liftIO getClockTime<br />
tell [Log t s]<br />
<br />
-- this handles one packet<br />
filterOne :: [Rule] -> Packet -> LogWriter (Maybe Packet)<br />
filterOne rules packet = do rule <- return (match rules packet)<br />
case rule of<br />
Nothing -> do logMsg ("DROPPING UNMATCHED PACKET: " ++ (show packet))<br />
return Nothing<br />
(Just r) -> do when (logIt r) (logMsg ("MATCH: " ++ (show r) ++ " <=> " ++ (show packet)))<br />
case r of<br />
(Rule Accept _ _) -> return (Just packet)<br />
(Rule Reject _ _) -> return Nothing<br />
<br />
-- this filters a list of packets, producing a filtered packet list<br />
-- and a log of the activity<br />
filterAll :: [Rule] -> [Packet] -> LogWriter [Packet]<br />
filterAll rules packets = do logMsg "STARTING PACKET FILTER"<br />
out <- mapM (filterOne rules) packets<br />
logMsg "STOPPING PACKET FILTER"<br />
return (catMaybes out)<br />
<br />
-- read the rule data from the file named in the first argument, and the packet data from<br />
-- the file named in the second argument, and then print the accepted packets followed by<br />
-- a log generated during the computation.<br />
main :: IO ()<br />
main = do args <- getArgs<br />
ruleData <- readFile (args!!0)<br />
packetData <- readFile (args!!1)<br />
let rules = (read ruleData)::[Rule]<br />
packets = (read packetData)::[Packet]<br />
(out,log) <- runWriterT (filterAll rules packets)<br />
putStrLn "ACCEPTED PACKETS"<br />
putStr (unlines (map show out))<br />
putStrLn "\n\nFIREWALL LOG"<br />
putStr (unlines (map show log))<br />
</haskell><br />
== ReaderT with IO ==<br />
<br />
If you found that one too easy, move on to a slightly more complex example: convert the [[readermonad.html#example|template system]] in example 16 from using a single template file with named templates to treating individual files as templates. One possible solution is shown in [[../examples/example23.hs|example 23]], but try to do it without looking first.<br />
<br />
== StateT with List ==<br />
<br />
The previous examples have all been using the IO monad as the inner monad. Here is a more interesting example: combining <code>StateT</code> with the List monad to produce a monad for stateful nondeterministic computations.<br />
<br />
We will apply this powerful monad combination to the task of solving constraint satisfaction problems (in this case, a logic problem). The idea behind it is to have a number of variables that can take on different values and a number of predicates involving those variables that must be satisfied. The current variable assignments and the predicates make up the state of the computation, and the non-deterministic nature of the List monad allows us to easily test all combinations of variable assignments.<br />
<br />
We start by laying the groundwork we will need to represent the logic problem, a simple predicate language:<br />
<br />
Code available in [[../examples/example24.hs|example24.hs]]<br />
<br />
<haskell><br />
-- First, we develop a language to express logic problems<br />
type Var = String<br />
type Value = String<br />
data Predicate = Is Var Value -- var has specific value<br />
| Equal Var Var -- vars have same (unspecified) value<br />
| And Predicate Predicate -- both are true<br />
| Or Predicate Predicate -- at least one is true<br />
| Not Predicate -- it is not true<br />
deriving (Eq, Show)<br />
<br />
type Variables = [(Var,Value)]<br />
<br />
-- test for a variable NOT equaling a value<br />
isNot :: Var -> Value -> Predicate<br />
isNot var value = Not (Is var value)<br />
<br />
-- if a is true, then b must also be true<br />
implies :: Predicate -> Predicate -> Predicate<br />
implies a b = Not (a `And` (Not b))<br />
<br />
-- exclusive or<br />
orElse :: Predicate -> Predicate -> Predicate<br />
orElse a b = (a `And` (Not b)) `Or` ((Not a) `And` b)<br />
<br />
-- Check a predicate with the given variable bindings.<br />
-- An unbound variable causes a Nothing return value.<br />
check :: Predicate -> Variables -> Maybe Bool<br />
check (Is var value) vars = do val <- lookup var vars<br />
return (val == value)<br />
check (Equal v1 v2) vars = do val1 <- lookup v1 vars<br />
val2 <- lookup v2 vars<br />
return (val1 == val2)<br />
check (And p1 p2) vars = liftM2 (&&) (check p1 vars) (check p2 vars)<br />
check (Or p1 p2) vars = liftM2 (||) (check p1 vars) (check p2 vars)<br />
check (Not p) vars = liftM (not) (check p vars)<br />
</haskell><br />
The next thing we will need is some code for representing and solving constraint satisfaction problems. This is where we will define our combined monad.<br />
<br />
Code available in [[../examples/example24.hs|example24.hs]]<br />
<br />
<haskell><br />
-- this is the type of our logic problem<br />
data ProblemState = PS {vars::Variables, constraints::[Predicate]}<br />
<br />
-- this is our monad type for non-determinstic computations with state<br />
type NDS a = StateT ProblemState [] a<br />
<br />
-- lookup a variable<br />
getVar :: Var -> NDS (Maybe Value)<br />
getVar v = do vs <- gets vars<br />
return $ lookup v vs<br />
<br />
-- set a variable<br />
setVar :: Var -> Value -> NDS ()<br />
setVar v x = do st <- get<br />
vs' <- return $ filter ((v/=).fst) (vars st)<br />
put $ st {vars=(v,x):vs'}<br />
<br />
-- Check if the variable assignments satisfy all of the predicates.<br />
-- The partial argument determines the value used when a predicate returns<br />
-- Nothing because some variable it uses is not set. Setting this to True<br />
-- allows us to accept partial solutions, then we can use a value of<br />
-- False at the end to signify that all solutions should be complete.<br />
isConsistent :: Bool -> NDS Bool<br />
isConsistent partial = do cs <- gets constraints<br />
vs <- gets vars<br />
let results = map (\p->check p vs) cs<br />
return $ and (map (maybe partial id) results)<br />
<br />
-- Return only the variable bindings that are complete consistent solutions.<br />
getFinalVars :: NDS Variables<br />
getFinalVars = do c <- isConsistent False<br />
guard c<br />
gets vars<br />
<br />
-- Get the first solution to the problem, by evaluating the solver computation with<br />
-- an initial problem state and then returning the first solution in the result list,<br />
-- or Nothing if there was no solution.<br />
getSolution :: NDS a -> ProblemState -> Maybe a<br />
getSolution c i = listToMaybe (evalStateT c i)<br />
<br />
-- Get a list of all possible solutions to the problem by evaluating the solver<br />
-- computation with an initial problem state.<br />
getAllSolutions :: NDS a -> ProblemState -> [a]<br />
getAllSolutions c i = evalStateT c i<br />
</haskell><br />
We are ready to apply the predicate language and stateful nondeterministic monad to solving a logic problem. For this example, we will use the well-known Kalotan puzzle which appeared in ''Mathematical Brain-Teasers'', Dover Publications (1976), by J. A. H. Hunter.<br />
<br />
<blockquote>The Kalotans are a tribe with a peculiar quirk: their males always tell the truth. Their females never make two consecutive true statements, or two consecutive untrue statements. An anthropologist (let's call him Worf) has begun to study them. Worf does not yet know the Kalotan language. One day, he meets a Kalotan (heterosexual) couple and their child Kibi. Worf asks Kibi: ``Are you a boy?'' The kid answers in Kalotan, which of course Worf doesn't understand. Worf turns to the parents (who know English) for explanation. One of them says: &quot;Kibi said: `I am a boy.'&quot; The other adds: &quot;Kibi is a girl. Kibi lied.&quot; Solve for the sex of Kibi and the sex of each parent.</blockquote><br />
We will need some additional predicates specific to this puzzle, and to define the universe of allowed variables values:<br />
<br />
Code available in [[../examples/example24.hs|example24.hs]]<br />
<br />
<haskell><br />
-- if a male says something, it must be true<br />
said :: Var -> Predicate -> Predicate<br />
said v p = (v `Is` "male") `implies` p<br />
<br />
-- if a male says two things, they must be true<br />
-- if a female says two things, one must be true and one must be false<br />
saidBoth :: Var -> Predicate -> Predicate -> Predicate<br />
saidBoth v p1 p2 = And ((v `Is` "male") `implies` (p1 `And` p2))<br />
((v `Is` "female") `implies` (p1 `orElse` p2))<br />
<br />
-- lying is saying something is true when it isn't or saying something isn't true when it is<br />
lied :: Var -> Predicate -> Predicate<br />
lied v p = ((v `said` p) `And` (Not p)) `orElse` ((v `said` (Not p)) `And` p)<br />
<br />
-- Test consistency over all allowed settings of the variable.<br />
tryAllValues :: Var -> NDS ()<br />
tryAllValues var = do (setVar var "male") `mplus` (setVar var "female")<br />
c <- isConsistent True<br />
guard c<br />
</haskell><br />
All that remains to be done is to define the puzzle in the predicate language and get a solution that satisfies all of the predicates:<br />
<br />
Code available in [[../examples/example24.hs|example24.hs]]<br />
<br />
<haskell><br />
-- Define the problem, try all of the variable assignments and print a solution.<br />
main :: IO ()<br />
main = do let variables = []<br />
constraints = [ Not (Equal "parent1" "parent2"),<br />
"parent1" `said` ("child" `said` ("child" `Is` "male")),<br />
saidBoth "parent2" ("child" `Is` "female")<br />
("child" `lied` ("child" `Is` "male")) ]<br />
problem = PS variables constraints<br />
print $ (`getSolution` problem) $ do tryAllValues "parent1"<br />
tryAllValues "parent2"<br />
tryAllValues "child"<br />
getFinalVars<br />
</haskell><br />
Each call to <code>tryAllValues</code> will fork the solution space, assigning the named variable to be <code>"male"</code> in one fork and <code>"female"</code> in the other. The forks which produce inconsistent variable assignments are eliminated (using the <code>guard</code> function). The call to <code>getFinalVars</code> applies <code>guard</code> again to eliminate inconsistent variable assignments and returns the remaining assignments as the value of the computation.<br />
<br />
Managing the transformer stack<br />
<br />
= Managing the transformer stack =<br />
<br />
As the number of monads combined together increases, it becomes increasingly important to manage the stack of monad transformers well.<br />
<br />
== Selecting the correct order ==<br />
<br />
Once you have decided on the monad features you need, you must choose the correct order in which to apply the monad transformers to achieve the results you want. For instance you may know that you want a combined monad that is an instance of <code>MonadError</code> and <code>MonadState</code>, but should you apply <code>StateT</code> to the <code>Error</code> monad or <code>ErrorT</code> to the <code>State</code> monad?<br />
<br />
The decision depends on the exact semantics you want for your combined monad. Applying <code>StateT</code> to the <code>Error</code> monad gives a state transformer function of type <code>s -> Error e (a,s)</code>. Applying <code>ErrorT</code> to the <code>State</code> monad gives a state transformer function of type <code>s -> (Error e a,s)</code>. Which order to choose depends on the role of errors in your computation. If an error means no state could be produced, you would apply <code>StateT</code> to <code>Error</code>. If an error means no value could be produced, but the state remains valid, then you would apply <code>ErrorT</code> to <code>State</code>.<br />
<br />
Choosing the correct order requires understanding the transformation carried out by each monad transformer, and how that transformation affects the semantics of the combined monad.<br />
<br />
== An example with multiple transformers ==<br />
<br />
The following example demonstrates the use of multiple monad transformers. The code uses the StateT monad transformer along with the List monad to produce a combined monad for doing stateful nondeterministic computations. In this case, however, we have added the <code>WriterT</code> monad transformer to perform logging during the computation. The problem we will apply this monad to is the famous N-queens problem: to place N queens on a chess board so that no queen can attack another.<br />
<br />
The first decision is in what order to apply the monad transformers. <code>StateT s (WriterT w [])</code> yields a type like: <code>s -> [((a,s),w)]</code>. <code>WriterT w (StateT s [])</code> yields a type like: <code>s -> [((a,w),s)]</code>. In this case, there is little difference between the two orders, so we will choose the second arbitrarily.<br />
<br />
Our combined monad is an instance of both <code>MonadState</code> and <code>MonadWriter</code>, so we can freely mix use of <code>get</code>, <code>put</code>, and <code>tell</code> in our monadic computations.<br />
<br />
Code available in [[../examples/example25.hs|example25.hs]]<br />
<br />
<haskell><br />
-- this is the type of our problem description<br />
data NQueensProblem = NQP {board::Board,<br />
ranks::[Rank], files::[File],<br />
asc::[Diagonal], desc::[Diagonal]}<br />
<br />
-- initial state = empty board, all ranks, files, and diagonals free<br />
initialState = let fileA = map (\r->Pos A r) [1..8]<br />
rank8 = map (\f->Pos f 8) [A .. H]<br />
rank1 = map (\f->Pos f 1) [A .. H]<br />
asc = map Ascending (nub (fileA ++ rank1))<br />
desc = map Descending (nub (fileA ++ rank8))<br />
in NQP (Board []) [1..8] [A .. H] asc desc<br />
<br />
-- this is our combined monad type for this problem<br />
type NDS a = WriterT [String] (StateT NQueensProblem []) a<br />
<br />
-- Get the first solution to the problem, by evaluating the solver computation with<br />
-- an initial problem state and then returning the first solution in the result list,<br />
-- or Nothing if there was no solution.<br />
getSolution :: NDS a -> NQueensProblem -> Maybe (a,[String])<br />
getSolution c i = listToMaybe (evalStateT (runWriterT c) i)<br />
<br />
-- add a Queen to the board in a specific position<br />
addQueen :: Position -> NDS ()<br />
addQueen p = do (Board b) <- gets board<br />
rs <- gets ranks<br />
fs <- gets files<br />
as <- gets asc<br />
ds <- gets desc<br />
let b' = (Piece Black Queen, p):b<br />
rs' = delete (rank p) rs<br />
fs' = delete (file p) fs<br />
(a,d) = getDiags p<br />
as' = delete a as<br />
ds' = delete d ds<br />
tell ["Added Queen at " ++ (show p)]<br />
put (NQP (Board b') rs' fs' as' ds')<br />
<br />
-- test if a position is in the set of allowed diagonals<br />
inDiags :: Position -> NDS Bool<br />
inDiags p = do let (a,d) = getDiags p<br />
as <- gets asc<br />
ds <- gets desc<br />
return $ (elem a as) && (elem d ds)<br />
<br />
-- add a Queen to the board in all allowed positions<br />
addQueens :: NDS ()<br />
addQueens = do rs <- gets ranks<br />
fs <- gets files<br />
allowed <- filterM inDiags [Pos f r | f <- fs, r <- rs]<br />
tell [show (length allowed) ++ " possible choices"]<br />
msum (map addQueen allowed)<br />
<br />
-- Start with an empty chess board and add the requested number of queens,<br />
-- then get the board and print the solution along with the log<br />
main :: IO ()<br />
main = do args <- getArgs<br />
let n = read (args!!0)<br />
cmds = replicate n addQueens<br />
sol = (`getSolution` initialState) $ do sequence_ cmds<br />
gets board<br />
case sol of<br />
Just (b,l) -> do putStr $ show b -- show the solution<br />
putStr $ unlines l -- show the log<br />
Nothing -> putStrLn "No solution"<br />
</haskell><br />
The program operates in a similar manner to the previous example, which solved the kalotan puzzle. In this example, however, we do not test for consistency using the <code>guard</code> function. Instead, we only create branches that correspond to allowed queen positions. We use the added logging facility to log the number of possible choices at each step and the position in which the queen was placed.<br />
<br />
== Heavy lifting ==<br />
<br />
There is one subtle problem remaining with our use of multiple monad transformers. Did you notice that all of the computations in the previous example are done in the combined monad, even if they only used features of one monad? The code for these functions in tied unneccessarily to the definition of the combined monad, which decreases their reusability.<br />
<br />
This is where the <code>lift</code> function from the <code>MonadTrans</code> class comes into its own. The <code>lift</code> function gives us the ability to write our code in a clear, modular, reusable manner and then lift the computations into the combined monad as needed.<br />
<br />
Instead of writing brittle code like:<br />
<br />
<haskell><br />
logString :: String -> StateT MyState (WriterT [String] []) Int<br />
logString s = ...<br />
</haskell><br />
we can write clearer, more flexible code like:<br />
<br />
<haskell><br />
logString :: (MonadWriter [String] m) => String -> m Int<br />
logString s = ...<br />
</haskell><br />
and then lift the <code>logString</code> computation into the combined monad when we use it.<br />
<br />
[[Image:info.png]] You may need to use the compiler flags <code>-fglasgow-exts</code> with GHC or the equivalent flags with your Haskell compiler to use this technique. The issue is that <code>m</code> in the constraint above is a type constructor, not a type, and this is not supported in standard Haskell 98. <br /><br />
<br />
<br />
When using lifting with complex transformer stacks, you may find yourself composing multiple lifts, like <code>lift . lift . lift $ f x</code>. This can become hard to follow, and if the transformer stack changes (perhaps you add <code>ErrorT</code> into the mix) the lifting may need to be changed all over the code. A good practice to prevent this is to declare helper functions with informative names to do the lifting:<br />
<br />
<haskell><br />
liftListToState = lift . lift . lift<br />
</haskell><br />
Then, the code is more informative and if the transformer stack changes, the impact on the lifting code is confined to a small number of these helper functions.<br />
<br />
The hardest part about lifting is understanding the semantics of lifting computations, since this depends on the details of the inner monad and the transformers in the stack. As a final task, try to understand the different roles that lifting plays in the following example code. Can you predict what the output of the program will be?<br />
<br />
Code available in [[../examples/example26.hs|example26.hs]]<br />
<br />
<haskell><br />
-- this is our combined monad type for this problem<br />
type NDS a = StateT Int (WriterT [String] []) a<br />
<br />
{- Here is a computation on lists -}<br />
<br />
-- return the digits of a number as a list<br />
getDigits :: Int -> [Int]<br />
getDigits n = let s = (show n)<br />
in map digitToInt s<br />
<br />
{- Here are some computations in MonadWriter -}<br />
<br />
-- write a value to a log and return that value<br />
logVal :: (MonadWriter [String] m) => Int -> m Int<br />
logVal n = do tell ["logVal: " ++ (show n)]<br />
return n<br />
<br />
-- do a logging computation and return the length of the log it wrote<br />
getLogLength :: (MonadWriter [[a]] m) => m b -> m Int<br />
getLogLength c = do (_,l) <- listen $ c<br />
return (length (concat l))<br />
<br />
-- log a string value and return 0<br />
logString :: (MonadWriter [String] m) => String -> m Int<br />
logString s = do tell ["logString: " ++ s]<br />
return 0<br />
<br />
{- Here is a computation that requires a WriterT [String] [] -}<br />
<br />
-- "Fork" the computation and log each list item in a different branch.<br />
logEach :: (Show a) => [a] -> WriterT [String] [] a<br />
logEach xs = do x <- lift xs<br />
tell ["logEach: " ++ (show x)]<br />
return x<br />
<br />
{- Here is a computation in MonadState -}<br />
<br />
-- increment the state by a specified value<br />
addVal :: (MonadState Int m) => Int -> m ()<br />
addVal n = do x <- get<br />
put (x+n)<br />
<br />
{- Here are some computations in the combined monad -}<br />
<br />
-- set the state to a given value, and log that value<br />
setVal :: Int -> NDS ()<br />
setVal n = do x <- lift $ logVal n<br />
put x<br />
<br />
-- "Fork" the computation, adding a different digit to the state in each branch.<br />
-- Because setVal is used, the new values are logged as well.<br />
addDigits :: Int -> NDS ()<br />
addDigits n = do x <- get<br />
y <- lift . lift $ getDigits n<br />
setVal (x+y)<br />
<br />
{- an equivalent construction is:<br />
addDigits :: Int -> NDS ()<br />
addDigits n = do x <- get<br />
msum (map (\i->setVal (x+i)) (getDigits n))<br />
-}<br />
<br />
{- This is an example of a helper function that can be used to put all of the lifting logic<br />
in one location and provide more informative names. This has the advantage that if the<br />
transformer stack changes in the future (say, to add ErrorT) the changes to the existing<br />
lifting logic are confined to a small number of functions.<br />
-}<br />
liftListToNDS :: [a] -> NDS a<br />
liftListToNDS = lift . lift<br />
<br />
-- perform a series of computations in the combined monad, lifting computations from other<br />
-- monads as necessary.<br />
main :: IO ()<br />
main = do mapM_ print $ runWriterT $ (`evalStateT` 0) $ do x <- lift $ getLogLength $ logString "hello"<br />
addDigits x<br />
x <- lift $ logEach [1,3,5]<br />
lift $ logVal x<br />
liftListToNDS $ getDigits 287<br />
<br />
</haskell><br />
Once you fully understand how the various lifts in the example work and how lifting promotes code reuse, you are ready for real-world monadic programming. All that is left to do is to hone your skills writing real software. Happy hacking!<br />
<br />
Continuing Exploration<br />
<br />
= Continuing Exploration =<br />
<br />
This brings us to the end of this tutorial. If you want to continue learning about the mathematical foundations of monads, there are numerous [http://plato.stanford.edu/entries/category-theory/ category theory] resources on the internet. For more examples of monads and their applications in the real world, you might want to explore the design of the [http://www.cs.uu.nl/people/daan/papers/parsec.html Parsec] monadic parser combinator library and/or the [http://www.math.chalmers.se/~rjmh/QuickCheck/ QuickCheck] testing tool. You may also be interested in [http://www.haskell.org/arrows/ arrows], which are similar to monads but more general.<br />
<br />
If you discover any errors — no matter how small — in this document, or if you have suggestions for how it can be improved, please write to the author at [mailto:jnewbern@yahoo.com jnewbern@yahoo.com].<br />
<br />
A physical analogy for monads<br />
<br />
= A physical analogy for monads =<br />
<br />
Because monads are such abstract entities, it is sometimes useful to think about a physical system that is analogous to a monad instead of thinking about monads directly. In this way, we can use our physical intuition and experiences to gain insights that we can relate back to the abstract world of computational monads.<br />
<br />
The particular physical analogy developed here is that of a mechanized assembly line. It is not a perfect fit for monads — especially with some of the higher-order aspects of monadic computation — but I believe it could be helpful to gain the initial understanding of how a monad works.<br />
<br />
Begin by thinking about a Haskell program as a conveyor belt. Input goes on end of the conveyor belt and is carried to a succession of work areas. At each work area, some operation is performed on the item on the conveyor belt and the result is carried by the conveyor belt to the next work area. Finally, the conveyor belt carries the final product to the end of the assembly line to be output.<br />
<br />
In this assembly line model, our physical monad is a system of machines that controls how successive work areas on the assembly line combine their functionality to create the overall product.<br />
<br />
Our monad consists of three parts:<br />
<br />
# Trays that hold work products as they move along the conveyor belt.<br />
# Loader machines that can put any object into a tray.<br />
# Combiner machines that can take a tray with an object and produce a tray with a new object. These combiner machines are attached to worker machines that actualy produce the new objects.<br />
<br />
We use the monad by setting up our assembly line as a loader machine which puts materials into trays at the beginning of the assembly line. The conveyor belt then carries these trays to each work area, where a combiner machine takes the tray and may decide based on its contents whether to run them through a worker machine, as shown in Figure A-1.<br />
<br />
<table><br />
<tbody><br />
<tr class="odd"><br />
<td align="left">[[Image:figureA-1.png]]</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">Figure A-1. An assembly line using a monad architecture.</td><br />
</tr><br />
</tbody><br />
</table><br />
<br />
The important thing to notice about the monadic assembly line is that it separates out the work of combining the output of the worker machines from the actual work done by the worker machines. Once they are separated, we can vary them independently. So the same combiner machines could be used on an assembly line to make airplanes and an assembly line to make chopsticks. Likewise, the same worker machines could be used with different combiners to alter the way the final product is produced.<br />
<br />
Lets take the example of an assembly line to make chopsticks, and see how it is handled in our physical analogy and how me might represent it as a program in Haskell. We will have three worker machines. The first takes small pieces of wood as input and outputs a tray containing a pair of roughly shaped chopsticks. The second takes a pair of roughly shaped chopsticks and outputs a tray containing a pair of smooth, polished chopsticks with the name of the restaurant printed on them. The third takes a pair of polished chopsticks and outputs a tray containing a finished pair of chopsticks in a printed paper wrapper. We could represent this in Haskell as:<br />
<br />
<haskell><br />
-- the basic types we are dealing with<br />
type Wood = ...<br />
type Chopsticks = ...<br />
data Wrapper x = Wrapper x<br />
<br />
-- NOTE: the Tray type comes from the Tray monad<br />
<br />
-- worker function 1: makes roughly shaped chopsticks<br />
makeChopsticks :: Wood -> Tray Chopsticks<br />
makeChopsticks w = ...<br />
<br />
-- worker function 2: polishes chopsticks<br />
polishChopsticks :: Chopsticks -> Tray Chopsticks<br />
polishChopsticks c = ...<br />
<br />
-- worker function 3: wraps chopsticks<br />
wrapChopsticks :: Chopsticks -> Tray Wrapper Chopsticks<br />
wrapChopsticks c = ...<br />
</haskell><br />
It is clear that the worker machines contain all of the functionality needed to produce chopsticks. What is missing is the specification of the trays, loader, and combiner machines that collectively make up the Tray monad. Our trays should either be empty or contain a single item. Our loader machine would simply take an item and place it in a tray on the conveyor belt. The combiner machine would take each input tray and pass along empty trays while feeding the contents of non-empty trays to its worker machine. In Haskell, we would define the <code>Tray</code> monad as:<br />
<br />
<haskell><br />
-- trays are either empty or contain a single item <br />
data Tray x = Empty | Contains x<br />
<br />
-- Tray is a monad<br />
instance Monad Tray where<br />
Empty >>= _ = Empty<br />
(Contains x) >>= worker = worker x<br />
return = Contains<br />
fail _ = Empty <br />
</haskell><br />
[[Image:info.png]] You may recognize the <code>Tray</code> monad as a disguised version of the <code>Maybe</code> monad that is a standard part of Haskell 98 library. <br /><br />
<br />
<br />
All that remains is to sequence the worker machines together using the loader and combiner machines to make a complete assembly line, as shown in Figure A-2.<br />
<br />
<table><br />
<tbody><br />
<tr class="odd"><br />
<td align="left">[[Image:figureA-2.png]]</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">Figure A-2. A complete assembly line for making chopsticks using a monadic approach.</td><br />
</tr><br />
</tbody><br />
</table><br />
<br />
In Haskell, the sequencing can be done using the standard monadic functions:<br />
<br />
<haskell><br />
assemblyLine :: Wood -> Tray Wrapped Chopsticks<br />
assemblyLine w = (return w) >>= makeChopsticks >>= polishChopsticks >>= wrapChopsticks<br />
</haskell><br />
or using the built in Haskell &quot;do&quot; notation for monads:<br />
<br />
<haskell><br />
assemblyLine :: Wood -> Tray Wrapped Chopsticks<br />
assemblyLine w = do c <- makeChopsticks w<br />
c' <- polishChopsticks c<br />
c'' <- wrapChopsticks c'<br />
return c''<br />
</haskell><br />
So far, you have seen how monads are like a framework for building assembly lines, but you probably haven't been overawed by their utility. To see why we might want to build our assembly line using the monadic approach, consider what would happen if we wanted to change the manufacturing process.<br />
<br />
Right now, when a worker machine malfunctions, it uses the <code>fail</code> routine to produce an empty tray. The <code>fail</code> routine takes an argument describing the failure, but our <code>Tray</code> type ignores this and simply produces an empty tray. This empty tray travels down the assembly line and the combiner machines allow it to bypass the remaining worker machines. It eventually reaches the end of the assembly line, where it is brought to you, the quality control engineer. It is your job to figure out which machine failed, but all you have to go on is an empty tray.<br />
<br />
You realize that your job would be much easier if you took advantage of the failure messages that are currently ignored by the <code>fail</code> routine in your <code>Tray</code> monad. Because your assembly line is organized around a monadic approach, it is easy for you to add this functionality to your assembly line without changing your worker machines.<br />
<br />
To make the change, you simply create a new tray type that can never be empty. It will always either contain an item or it will contain a failure report describing the exact reason there is no item in the tray.<br />
<br />
<haskell><br />
-- tray2s either contain a single item or contain a failure report <br />
data Tray2 x = Contains x | Failed String<br />
<br />
-- Tray2 is a monad<br />
instance Monad Tray2 where<br />
(Failed reason) >>= _ = Failed reason<br />
(Contains x) >>= worker = worker x<br />
return = Contains<br />
fail reason = Failed reason<br />
</haskell><br />
[[Image:info.png]] You may recognize the <code>Tray2</code> monad as a disguised version of the <code>Error</code> monad that is a standard part of the Haskell 98 libraries.<br /><br />
<br />
<br />
Replacing the <code>Tray</code> monad with the <code>Tray2</code> monad instantly upgrades your assembly line. Now when a failure occurs, the tray that is brought to the quality control engineer contains a failure report detailing the exact cause of the failure!<br />
<br />
Haskell code examples<br />
<br />
= Haskell code examples =<br />
<br />
This appendix contains a list of all of the code [[../examples/|examples]] supplied with the tutorial. The source code can be [http://web.archive.org/web/20061210172052/http://www.nomaware.com/monads/html/examples.html found here].<br />
<br />
== [[../examples/example1.hs|Example 1]] ==<br />
<br />
This example is discussed in the section: [[meet.html#example1|Meet the monads]].<br />
<br />
The example code introduces the monad concept without using Haskell typeclasses. It shows how a monadic combinator can be used to simplify the construction of computations from sequences of computations which may not return a result.<br />
<br />
== [[../examples/example2.hs|Example 2]] ==<br />
<br />
This example is discussed in the section: [[class.html#example2|Doing it with class]].<br />
<br />
The example code builds on the first example, and shows how do-notation can be used with an instance of the <code>Monad</code> class (in this case, <code>Maybe</code> is the monad used).<br />
<br />
== [[../examples/example3.hs|Example 3]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example3|Monad support in Haskell]].<br />
<br />
The example code builds on the first two examples, and shows a somewhat atypical — but very powerful — use of the <code>foldM</code> function outside of a do-block.<br />
<br />
== [[../examples/example4.hs|Example 4]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example4|Monad support in Haskell]].<br />
<br />
The example code shows a more typical use of the <code>foldM</code> function within a do-block. It combines dictionary values read from different files into a single dictionary using the <code>foldM</code> function within the IO monad.<br />
<br />
== [[../examples/example5.hs|Example 5]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example5|Monad support in Haskell]].<br />
<br />
The example code shows the use of the <code>filterM</code> function within a do-block. It prints the subset of its arguments that specify directories and ignores non-directory arguments.<br />
<br />
== [[../examples/example6.hs|Example 6]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example6|Monad support in Haskell]].<br />
<br />
The example code shows the use of the <code>liftM</code> function within a do-block. It looks up a name in a list and uses a lifted String manipulation function to modify it within the Maybe monad.<br />
<br />
== [[../examples/example7.hs|Example 7]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example7|Monad support in Haskell]].<br />
<br />
The example code shows a higher-order application of <code>liftM2</code>. It folds lifted operations within the List monad to produce lists of all combinations of elements combined with the lifted operator.<br />
<br />
== [[../examples/example8.hs|Example 8]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example8|Monad support in Haskell]].<br />
<br />
The example code shows a higher-order application of <code>ap</code>. It folds <code>ap</code> through a list of <code>Maybe (a->a)</code> functions to process sequences of commands.<br />
<br />
== [[../examples/example9.hs|Example 9]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example9|Monad support in Haskell]].<br />
<br />
The example code shows the use of <code>msum</code> in the Maybe monad to select the first variable match in a stack of binding environments.<br />
<br />
== [[../examples/example10.hs|Example 10]] ==<br />
<br />
This example is discussed in the section: [[monadfns.html#example10|Monad support in Haskell]].<br />
<br />
The example code shows the use of <code>guard</code> in the Maybe monad to select only the records from a list that satisfy a predicate (equivalent to <code>filter</code>).<br />
<br />
== [[../examples/example11.hs|Example 11]] ==<br />
<br />
This example is discussed in the section: [[maybemonad.html#example|The Maybe monad]].<br />
<br />
The example code shows how to use the <code>Maybe</code> monad to build complex queries from simpler queries that may fail to return a result. The specific example used is looking up mail preferences for someone based on either their full name or a nickname.<br />
<br />
== [[../examples/example12.hs|Example 12]] ==<br />
<br />
This example is discussed in the section: [[errormonad.html#example|The Error monad]].<br />
<br />
The example code demonstrates the use of the <code>Either</code> type constructor as an <code>Error</code> monad with a custom error type. The example parses hexadecimal digits and uses the exception handling mechanism of the <code>Error</code> monad to provide informative error messages in the event of a parse failure.<br />
<br />
== [[../examples/example13.hs|Example 13]] ==<br />
<br />
This example is discussed in the section: [[listmonad.html#example|The List monad]].<br />
<br />
The example code uses the built-in list type constructor as a monad for non-deterministic computation. The example demonstrates parsing an ambiguous grammar consisting of integers, hex values, and words.<br />
<br />
== [[../examples/example14.hs|Example 14]] ==<br />
<br />
This example is discussed in the section: [[iomonad.html#example|The IO monad]].<br />
<br />
The example code implements a simple version of the standard Unix command &quot;tr&quot;. The example demonstrates use of the IO monad including implicit <code>fail</code> calls due to pattern matching failures and the use of <code>catcherror</code>.<br />
<br />
== [[../examples/example15.hs|Example 15]] ==<br />
<br />
This example is discussed in the section: [[statemonad.html#example|The State monad]].<br />
<br />
The example code shows how the State monad can be used instead of explicitly passing state. The example uses the State monad to manage the random number generator state while building a compound data value requiring multiple calls to the random number generator.<br />
<br />
== [[../examples/example16.hs|Example 16]] ==<br />
<br />
This example is discussed in the section: [[readermonad.html#example|The Reader monad]].<br />
<br />
The example code shows how the Reader monad can be used to simplify computations involving a shared environment. The example uses the Reader monad to implement a simple template substitution system. The example code demonstrates the use of the Parsec monadic parser combinator library.<br />
<br />
== [[../examples/example17.hs|Example 17]] ==<br />
<br />
This example is discussed in the section: [[writermonad.html#example|The Writer monad]].<br />
<br />
The example code shows how the Writer monad can be used to implement logging. The example implements a very simple firewall simulator and uses the Writer monad to log the firewall activity.<br />
<br />
== [[../examples/example18.hs|Example 18]] ==<br />
<br />
This example is discussed in the section: [[contmonad.html#example|The Continuation monad]].<br />
<br />
The example code shows how the Continuation monad's escape continuations work. The example computes a complex transformation of a number.<br />
<br />
== [[../examples/example19.hs|Example 19]] ==<br />
<br />
This example is discussed in the section: [[hardway.html#example1|Combining monads the hard way]].<br />
<br />
The example code shows how the Continuation monad can be nested within the IO monad given a suitable computational structure. The example is a slight modification of example 18.<br />
<br />
== [[../examples/example20.hs|Example 20]] ==<br />
<br />
This example is discussed in the section: [[hardway.html#example2|Combining monads the hard way]].<br />
<br />
The example code shows how the Continuation monad and IO monad can be used simultaneously, but without using monad transformers. The example builds on examples 18 and 19.<br />
<br />
== [[../examples/example21.hs|Example 21]] ==<br />
<br />
This example is discussed in the section: [[transformers.html#example|Monad transformers]].<br />
<br />
The example code shows how the transformer version of the Continuation monad can be used to create a combined monad for using continuations and doing I/O. The example builds on examples 18, 19 and 20.<br />
<br />
== [[../examples/example22.hs|Example 22]] ==<br />
<br />
This example is discussed in the section: [[standardxformers.html#example1|Standard monad transformers]].<br />
<br />
The example code shows how the transformer version of the Writer monad can be used to create a combined monad for logging and doing I/O. The example adds timestamps to the log entries of the firewall simulator from example 17.<br />
<br />
== [[../examples/example23.hs|Example 23]] ==<br />
<br />
This example is discussed in the section: [[standardxformers.html#example2|Standard monad transformers]].<br />
<br />
The example code shows how the transformer version of the Reader monad can be used to create a monad that combines a shared environment with I/O. The example converts the template system of example 16 to use files as templates.<br />
<br />
== [[../examples/example24.hs|Example 24]] ==<br />
<br />
This example is discussed in the section: [[standardxformers.html#example3|Standard monad transformers]].<br />
<br />
The example code uses the <code>StateT</code> transformer on the List monad to create a combined monad for doing non-deterministic stateful computations. The example uses the combined monad to solve a logic problem.<br />
<br />
== [[../examples/example25.hs|Example 25]] ==<br />
<br />
This example is discussed in the section: [[stacking.html#example|An example with multiple monad transformers]].<br />
<br />
The example code uses the <code>StateT</code> and <code>WriterT</code> transformers on the List monad to create a combined monad for doing non-deterministic stateful computations with logging. The example uses the combined monad to solve the N-queens problem.<br />
<br />
== [[../examples/example26.hs|Example 26]] ==<br />
<br />
This example is discussed in the section: [[stacking.html#lifting|Heavy lifting]].<br />
<br />
The example code demonstrates the use of the <code>lift</code> function and the necessity of managing its use in complex transformer stacks.<br />
<br />
[[Category:Monad]]<br />
[[Category:Standard classes]]<br />
[[Category:Standard libraries]]<br />
[[Category:Standard packages]]<br />
[[Category:Standard types]]<br />
[[Category:Tutorials]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Yi&diff=57207
Yi
2013-12-04T21:33:25Z
<p>CaleGibbard: /* Windows */ sp.</p>
<hr />
<div>[[Category:Applications]]<br />
<br />
[[Image:Yi-logo.png]]<br />
<br />
== About ==<br />
<br />
Yi is a text editor written in Haskell and extensible in Haskell. The goal of Yi is<br />
to provide a flexible, powerful and correct editor core<br />
scriptable in Haskell.<br />
<br />
Features:<br />
<br />
* A purely functional editor core;<br />
* Keybindings written as parsers of the input;<br />
* Emacs, Vim and Cua (subset) emulations provided by default;<br />
* Vty, GTK+ w/ Pango(via Gtk2Hs), and, in development, Cocoa and GTK+ w/ VTE frontends.<br />
<br />
The long term goal of the project is to make Yi the editor of choice for Haskell hackers.<br />
<br />
The main short term goal is to maximize Yi's Fun Factor. This includes:<br />
* Improve hackability (and therefore architecture)<br />
* Add cool features<br />
<br />
== Get Yi ==<br />
<br />
=== From Hackage ===<br />
<br />
Yi depends on the [http://haskell.org/platform Haskell Platform] which must be installed. Many Haskellers haven't installed this explicitly, as they have already installed most of the utilities it contains; to be sure you have everything that is needed, it is recommended that you explicitly install the Platform.<br />
<br />
Following that, simply: <br />
<br />
$ cabal update<br />
$ cabal install yi<br />
<br />
More information about the package is available at [http://hackage.haskell.org/package/yi Yi on Hackage].<br />
<br />
=== From GitHub ===<br />
<br />
See the GitHub [https://github.com/yi-editor/yi repository]. Or get it with git:<br />
<br />
$ git clone git://github.com/yi-editor/yi.git<br />
<br />
We try to keep the repository in a clean and buildable state, so it's "testable" for new users. Yi usually only works on the latest GHC release.<br />
<br />
''Note that the old yi-contrib repository is now just a subdirectory of the yi repo.''<br />
<br />
=== Platform Support ===<br />
<br />
==== GNU/Linux ====<br />
<br />
Some GNU/Linux distros have pre-built Yi packages. For Debian/Ubuntu packages, see [https://groups.google.com/forum/?fromgroups=#!topic/yi-devel/XSzWSv1HBmQ this post in the yi-devel mailing list].<br />
<br />
==== Mac OS X ====<br />
<br />
The easiest way to get Yi for Mac OS X is currently no different from the above. There is also a Yi release in MacPorts, but it might be very old, deprecated one. Please use the Hackage version instead.<br />
<br />
==== Windows ====<br />
<br />
The current version of Yi on Hackage (0.6.6.0) can be built on Windows.<br />
<br />
First, you should install the current version of [http://www.haskell.org/platform/windows.html Haskell Platform for Windows]. The version 2012.4.0.0 is known to work with Yi 0.6.6.0. Make sure that your Haskell compiler and tools are on your PATH.<br />
<br />
Next, you should install [http://www.gtk.org/download/win32.php GTK+ for Windows]. You have to use "All-in-one bundles", not individual packages. Download and unpack the archive, then again make sure that GTK+ utilities are on your PATH.<br />
<br />
Now, you can invoke cabal-Install from the command prompt.<br />
<br />
$ cabal update<br />
$ cabal install gtk2hs-buildtools<br />
$ cabal install gtk<br />
$ cabal install yi -f-vty -fpango<br />
<br />
Make sure that you do Configure with flag -f-vty -fpango to force enabling Pango and disabling Vty interface, since Vty is not supported in Windows.<br />
<br />
== Screenshots (0.3) ==<br />
<br />
[[Image:Yi-20070409.png|thumb|right|500px|The GTK frontend]]<br />
[[Image:Yi-20080114-vty.png|thumb|none|500px|The Vty frontend]]<br />
<br />
== News ==<br />
<br />
There is a Yi blog, that reports the important news about Yi, at [http://yi-editor.blogspot.com/ http://yi-editor.blogspot.com/]. It also delves into algorithms and the Yi internals.<br />
<br />
You can also check the [[/OldNews]].<br />
<br />
== Bugs ==<br />
<br />
Check/report bug reports here: [https://github.com/yi-editor/yi/issues GitHub issue tracker]<br />
<br />
== FAQs ==<br />
<br />
{{/FAQ}} <br />
<br />
== Contribute ==<br />
<br />
Fork the source on GitHub and send pull requests for merges. Or consult the yi-devel mailing list. Patches are always welcome. :)<br />
<br />
Otherwise, see [https://github.com/yi-editor/yi/issues the complete list of open issues] here. <br />
<br />
(Note you can start working on all issues in <br />
New/Accepted state, regardless of the owner of the issue. <br />
-- you can send an email to the list with your plan if unsure)<br />
<br />
Post your questions and follow up on [http://groups.google.com/group/yi-devel the yi-devel mailing list]. <br />
Some other pending tasks are described below.<br />
<br />
=== Write access policy ===<br />
<br />
One does not need write access to the repository to contribute. Please fork the main repository and send pull requests.<br />
<br />
Write access can however be granted, with the following disclaimer:<br />
<br />
* All people with write access can apply patches without prior approval. If one thinks a patch would be controversial, it might be a good idea to discuss it on the list though.<br />
* Try to not break the build. (By Murphy's law, if you do so it will happen at the most annoying moment...) So, always try to build before pushing patches. Bypassing Darcs's test build to record a patch indicates you should further improve your patch.<br />
* [[JeanPhilippeBernardy | I]] can at any time rollback a patch for whatever reason. This however should not upset the author of the patch. Most contributions are welcome, so a patch revert normally would only mean that a detail or two need to be worked out. (e.g. it breaks an important feature in some configuration, etc.)<br />
<br />
== Yi Ideas ==<br />
<br />
This section is meant to gather ideas people have for Yi.<br />
<br />
*Evolution to an IDE:<br />
:Show exact location of compilation errors: 80% of a Haskell project<br />
:Support for the GHCi debugger & others: 10 % of a Haskell project (Added bonus: greath for learning: trough the debugger, people learn the real execution flow of a Haskell program. Better if this is done inside an editor)<br />
:Integration of refactoring tools : 5 %<br />
:Edition: only 5%<br />
<br />
<br />
*An extension to GHCi to support documentation of symbols. <br />
:This seems to be (reasonably) straightforward, as GHCi already has :info. It would mean hacking the type environment (what about values?) to add documentation information. The main problem would seem to be populating this --- maybe hack haddock to produce something from the library docs? I assume that using package GHC uses the parent RTS (package GHC seems to be the way to go, but more investigation is required --- don?)<br />
<br />
*Views on data<br />
:Rather than just editing a file, you would open a view onto the file, i.e. there is no longer a 1-1 correspondence between buffers and files. Why? Well, for aggregate buffers (i.e., editing multiple files in the one view), or for multiple views of a file (e.g. AST and source-level). There would be some primitive ops for editing a buffer (insertChar, delete, etc.), which would then call update functions on anything observing that file.<br />
<br />
*Support for Perl style regular expressions<br />
:Emacs regexes don't support the same set of features; Perl regexes are more tersely powerful. This could be a good feature for luring users from vanilla Emacs.<br />
<br />
*Remote attach so I can work from home, but still use a remote machine<br />
:Like Emacs's server?<br />
<br />
*Haddock documentation<br />
:(no brainer), maybe associate with .hi files for binaries. <br />
<br />
*Maybe a class <code>YiShow</code>, which all config items must be a member of? This is to emulate describe-variable<br />
<br />
*Support for collaborative editing. This would be very good for #haskell work, and the text editor Gobby and its [http://gobby.0x539.de/trac/wiki/ObbyProtocol Obby protocol] seem to provide a candidate way of doing things.<br />
<br />
<br />
=== Borrowing from other editors ===<br />
Take some ideas from Emacs, some from vi, but don't stick them all together without a single core philosophy. Otherwise, you'll end up with an editor that looks like it was thrown together. Some people come from an Emacs background, some from vi, some from elsewhere, and ALL of them will want Yi to behave like their regular editor. The best way to do this is to have a single person make all the decisions on behavior.<br />
<br />
==== Emacs ====<br />
<br />
Coming from an Emacs background, I think a few things are essential,<br />
mainly the introspection capabilities of Emacs.<br />
<br />
===== Emacs goodness =====<br />
<br />
The following are things I like about Emacs, as an extensible<br />
environment, and miss in Yi:<br />
<br />
; Really good online documentation<br />
: Emacs can tell you a lot about a function or variable with a keypress--- the current value, where it is declared, and a hypertext formation string<br />
<br />
; Hooks-Extensibility<br />
: All (good) apps allow users to extend, through, e.g., hooks --- a list of functions that are run before/after some event (like saving a file)<br />
<br />
; List of must-have features<br />
: http://glyph.twistedmatrix.com/2008/12/emacs-test.html<br />
<br />
<br />
===== Emacs badness =====<br />
<br />
So, why replace it?:<br />
; ELisp<br />
: Dynamically scoped, Dynamically typed, ugly, old. 'Nuff said<br />
<br />
; What's a Parser?<br />
: A lot of apps in emacs do stuff with text, usually text that is in some language. There is no standard parser (like, e.g. parsec), so a lot of it is ugly handwritten spaghetti. This also means that adding analysis tools isn't really done (or done nicely).<br />
<br />
; ELisp again<br />
: Haskell is a lot cleaner to write, especially because of the large number of libraries.<br />
<br />
(See also [http://www.emacswiki.org/cgi-bin/wiki/WhyDoesElispSuck WhyDoesElispSuck] on the Emacs wiki.)<br />
<br />
===== Emacs maybeness (?) =====<br />
<br />
Some things that are sometimes bad, sometimes good:<br />
<br />
; Everything is a buffer<br />
: Makes some sense, but sometimes doesn't. It is nice to have uniform key bindings do the right thing (e.g., C-Space sets the mark, and the region can then be used, e.g. to delete a sequence of emails in Wl) Sometimes, however, you just want some sort of GUI widget.<br />
: OTOH, having the minibuffer be a special kind of buffer is a good idea.<br />
<br />
; Properties<br />
: It is possible to associate arbitrary properties with symbols. This means you can annotate a symbol and then use that information at a later date<br />
<br />
==== Vim? ====<br />
<br />
; good things<br />
: modal key editing -> configuration system is powerful enough!<br />
: light weight -> fast startup -> yi has this :)<br />
<br />
<br />
=== Ideas ===<br />
<br />
=== Implementation ===<br />
<br />
Considerations:<br />
<br />
; Interface to the runtime<br />
: The scheduler, docs, etc.<br />
<br />
; Introspection of e.g. what processes are running.<br />
: There are already libraries in Haskell for processes, but they don't give Yi any extra information --- we really want a layer on top. <br />
<br />
...<br />
<br />
== Trivia ==<br />
<br />
;Y I is the most recursive acronym. (Read it as combinators).<br />
;義, pronounced yi, means righteousness, one of the five virtues of confucianism.<br />
;Yi is the symbol for a yobi - the largest [http://en.wikipedia.org/wiki/Binary_prefix#Prefixes binary prefix], meaning 2^80<br />
<br />
== External links ==<br />
<br />
* Blog: http://yi-editor.blogspot.com/<br />
* Haddock: http://projects.haskell.org/yi/doc/<br />
* Repository: https://github.com/yi-editor/yi<br />
* Issues tracker: https://github.com/yi-editor/yi/issues<br />
* Hackage page: http://hackage.haskell.org/package/yi<br />
* IRC channel: #yi on Freenode</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Template_Haskell&diff=56987
Template Haskell
2013-10-12T20:57:59Z
<p>CaleGibbard: /* Template Haskell specification */</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html The user manual section on Template Haskell]<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html#th-quasiquotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 [formerly /bz/thdoc.htm]]<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj [formerly /bz/th3.htm]]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter.<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples are given in [http://hackage.haskell.org/package/haskell-src-meta haskell-src-meta].<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Introduction_to_IO&diff=56647
Introduction to IO
2013-08-23T06:53:04Z
<p>CaleGibbard: </p>
<hr />
<div>''(This page is intended as a quick introduction to how IO is treated in Haskell. It doesn't describe everything there is to know, but should give some idea of how things work.)''<br />
<br />
Haskell separates pure functions from computations where side effects<br />
must be considered by encoding those side effects as values of a<br />
particular type. Specifically, a value of type <code>(IO a)</code> is an action,<br />
which if executed would produce a value of type <code>a</code>.<br />
<br />
Some examples:<br />
<haskell><br />
getLine :: IO String<br />
putStrLn :: String -> IO () -- note that the result value is an empty tuple.<br />
randomRIO :: (Random a) => (a,a) -> IO a<br />
</haskell><br />
<br />
Ordinary Haskell evaluation doesn't cause this execution to occur. A<br />
value of type <code>(IO a)</code> is almost completely inert. In fact, the only IO<br />
action which can really be said to run in a compiled Haskell program<br />
is <code>main</code>.<br />
<br />
Armed with this knowledge, we can write a "hello, world" program:<br />
<haskell><br />
main :: IO ()<br />
main = putStrLn "Hello, World!"<br />
</haskell><br />
<br />
Now, so far, all this is great, but without a way to chain actions<br />
together end-to-end, we can't do a whole lot. So Haskell provides us<br />
with a few primitives for composing and chaining together IO actions.<br />
A simple one of these is:<br />
<haskell><br />
(>>) :: IO a -> IO b -> IO b<br />
</haskell><br />
where if <code>x</code> and <code>y</code> are IO actions, then <code>(x >> y)</code> is the action that<br />
performs <code>x</code>, dropping the result, then performs <code>y</code> and returns its<br />
result.<br />
Great, we can now write programs which do multiple things:<br />
<haskell><br />
main = putStrLn "Hello" >> putStrLn "World"<br />
</haskell><br />
will print "Hello" and "World" on separate lines.<br />
<br />
However, we don't yet have a way to chain actions in which we are<br />
allowed to use the result of the first in order to affect what the<br />
second action will do. This is accomplished by the following<br />
operation, called 'bind':<br />
<haskell><br />
(>>=) :: IO a -> (a -> IO b) -> IO b<br />
</haskell><br />
Now, <code>x >>= f</code> is the action that first performs the action <code>x</code>, and captures its result, passing it to <code>f</code>, which then computes a second action to be performed. That action is then carried out, and its result is the result of the overall computation.<br />
<br />
That's a mouthful, but once you see it in use, perhaps the idea will<br />
become clearer:<br />
<haskell><br />
main = putStrLn "Hello, what is your name?"<br />
>> getLine<br />
>>= \name -> putStrLn ("Hello, " ++ name ++ "!")<br />
</haskell><br />
<br />
This is most of what we need. In fact, this bind function is really<br />
successful, and we can define <code>(>>)</code> in terms of it:<br />
<haskell><br />
x >> y = x >>= const y<br />
</haskell><br />
<br />
In practice, it turns out to also be quite important to turn a value<br />
into an IO action which does nothing, and simply returns that value.<br />
This is quite handy near the end of a chain of actions, where we want<br />
to decide what to return ourselves, rather than leaving it up to the<br />
last action in the chain. So there's one more primitive,<br />
<haskell><br />
return :: a -> IO a<br />
</haskell><br />
which does just that.<br />
<br />
You might see do-notation all over the place in real Haskell programs. In<br />
do-notation, our example program might look like:<br />
<br />
<haskell><br />
main = do putStrLn "Hello, what is your name?"<br />
name <- getLine<br />
putStrLn ("Hello, " ++ name ++ "!")<br />
</haskell><br />
<br />
This is in fact entirely equivalent to the above form, and is<br />
translated into it by the Haskell compiler. So whenever you see a do<br />
block, you can just imagine a chain of applications of <code>(>>)</code> and <code>(>>=)</code>,<br />
and some lambdas when appropriate to capture the results of actions. An action on its own on a line in a do-block will be executed, and a line of the form <code>v <- x</code> will cause the action <code>x</code> to be run, and the result bound to the variable <code>v</code>.<br />
<br />
A common mistake is to put something other than an action in the place of <code>x</code>, usually some other value. If you want to make a variable binding inside a do-block which doesn't involve running an action, then you can use a line of the form <code>let a = b</code>, which, like an ordinary let-expression will define <code>a</code> to be the same as <code>b</code>, but the definition scopes over the remainder of the do-block.<br />
<br />
Note that there is no function:<br />
<haskell><br />
unsafe :: IO a -> a<br />
</haskell><br />
as this would defeat the referential transparency of Haskell --<br />
applying <code>unsafe</code> to the same IO action might return different things<br />
every time, and Haskell functions aren't allowed to behave that way.<br />
<br />
Now, I haven't really told you anything about monads in general yet.<br />
Most monads are actually rather unlike IO, but they do share the<br />
similar concepts of bind and return. For more on monads in general,<br />
see my [[Monads as containers]] article, or my [[Monads as computation]] article which give two different ways to look at what monads abstract.<br />
<br />
- [[User:CaleGibbard|CaleGibbard]]<br />
<br />
== Further reading ==<br />
<br />
* For a comprehensive tutorial on using IO monad, look at the [http://haskell.org/haskellwiki/IO_inside Haskell I/O inside: Down the Rabbit's Hole]<br />
* An explanation of the basic Monad functions, with examples, can be found in the reference guide [http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions], by Henk-Jan van Tuyl.<br />
* There is also more information on [[Avoiding IO|how to avoid IO]]<br />
<br />
[[Category:Idioms]]<br />
[[Category:Monad]]<br />
<br />
Languages: [[IO入門編|ja]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Newtype&diff=43585
Newtype
2011-12-11T20:44:20Z
<p>CaleGibbard: </p>
<hr />
<div>A <hask>newtype</hask> declaration creates a new type in much the same way as <hask>data</hask>. The syntax and usage of newtypes is virtually identical to that of data declarations - in fact, you can replace the <hask>newtype</hask> keyword with <hask>data</hask> and it'll still compile, indeed there's even a good chance your program will still work. The converse is not true, however - <hask>data</hask> can only be replaced with <hask>newtype</hask> if the type has ''exactly one constructor'' with ''exactly one field'' inside it.<br />
<br />
Some examples:<br />
<br />
<haskell><br />
newtype Fd = Fd CInt<br />
-- data Fd = Fd CInt would also be valid<br />
<br />
-- newtypes can have deriving clauses just like normal types<br />
newtype Identity a = Identity a<br />
deriving (Eq, Ord, Read, Show)<br />
<br />
-- record syntax is still allowed, but only for one field<br />
newtype State s a = State { runState :: s -> (s, a) }<br />
<br />
-- this is *not* allowed:<br />
-- newtype Pair a b = Pair { pairFst :: a, pairSnd :: b }<br />
-- but this is:<br />
data Pair a b = Pair { pairFst :: a, pairSnd :: b }<br />
-- and so is this:<br />
newtype Pair' a b = Pair' (a, b)<br />
</haskell><br />
<br />
Sounds pretty limited! So why does anyone use <hask>newtype</hask>?<br />
<br />
== The short version ==<br />
<br />
The restriction to one constructor with one field means that the new type and the type of the field are in direct correspondence:<br />
<br />
<haskell><br />
State :: (s -> (s, a)) -> State s a<br />
runState :: State s a -> (s -> (s, a))<br />
</haskell><br />
<br />
or in mathematical terms they are ''isomorphic''. This means that after the type is checked at compile time, at run time the two types can be treated essentially the same, without the overhead or indirection normally associated with a data constructor. So if you want to declare different type class instances for a particular type, or want to make a type abstract, you can wrap it in a <hask>newtype</hask> and it'll be considered distinct to the type-checker, but identical at runtime. You can then use all sorts of deep trickery like phantom or recursive types without worrying about GHC shuffling buckets of bytes for no reason.<br />
<br />
== The messy bits ==<br />
<br />
Why doesn't everyone just use <hask>newtype</hask> whenever they can, then? Well, quite often they do. But there is a subtle yet sematically significant difference. When we create a data type supposedly isomorphic to <hask>Bool</hask> like so:<br />
<br />
<haskell>data Any = Any { getAny :: Bool }</haskell><br />
<br />
we actually find that the isomorphism isn't exact:<br />
<br />
<haskell><br />
Any . getAny $ Any True = Any True -- okay, fine<br />
Any . getAny $ Any False = Any False -- also fine<br />
Any . getAny $ Any ⊥ = Any ⊥ -- so far so good<br />
Any . getAny $ ⊥ = Any ⊥ -- wait a second...<br />
</haskell><br />
([[Bottom|what's that upside-down T thing?]])<br />
<br />
The problem is that types declared with the <hask>data</hask> keyword are ''lifted'' - that is, they contain their own ⊥ value that is distinct from all the others. In this example, we have <hask>⊥ :: Any</hask> distinct from <hask>Any ⊥ :: Any</hask>. What this means is that the following pattern match:<br />
<br />
<haskell><br />
case x of<br />
Any _ -> ()<br />
</haskell><br />
<br />
must evaluate its argument, even though it seems like the pattern match can't fail: we must check whether <hask>x</hask> is <hask>⊥</hask> or <hask>Any y</hask> for some <hask>y</hask>.<br />
<br />
This is intrinsic to Haskell's lazy, non-total semantics. The problem is that this means tracking whether a value is wrapped in a constructor or not, which means keeping track of those extra constructors at runtime even when all they do is distinguish an extra bottom value we don't even want. So in order to be consistent, but also allow the exact isomorphism to be preserved, Haskell provides the <hask>newtype</hask> keyword, for the construction of unlifted types. Pattern-matching on a newtype constructor doesn't do any work, because there is no separate ⊥ so every value in the type is wrapped in the constructor.<br />
<br />
== What about strict types? ==<br />
<br />
You may notice that a type like<br />
<br />
<haskell>data Identity' a = Identity' !a</haskell><br />
<br />
has <hask>Identity' ⊥ = ⊥</hask> and so you might think you have your coveted isomorphism. But all the strictness annotation means is that <hask>Identity' ⊥</hask> really means <hask>Identity' $! ⊥</hask> - the semantics of the type are fundamentally the same, and in particular the case expression still forces the value.<br />
<br />
== Examples ==<br />
<br />
<haskell><br />
module Foo where<br />
<br />
data Foo1 = Foo1 Int -- Defines Foo1 constructor that lazily refers to an Int<br />
data Foo2 = Foo2 !Int -- Defines Foo2 constructor that strictly refers to an Int<br />
newtype Foo3 = Foo3 Int -- Defines Foo3 constructor that is synonymous with Int<br />
<br />
-- Argument is lazy and ignored, so <br />
-- undefined does not cause failure since<br />
-- the contructor pattern match succeeds.<br />
x1 = case Foo1 undefined of<br />
Foo1 _ -> 1 -- 1<br />
<br />
-- Argument is strict (because of !), so<br />
-- undefined does cause failure.<br />
x2 = case Foo2 undefined of<br />
Foo2 _ -> 1 -- undefined<br />
<br />
-- The newtype behaves like Int, see yInt below<br />
x3 = case Foo3 undefined of<br />
Foo3 _ -> 1 -- 1<br />
<br />
-- Constructor pattern match fails<br />
y1 = case undefined of<br />
Foo1 _ -> 1 -- undefined<br />
<br />
-- Constructor pattern match fails<br />
y2 = case undefined of<br />
Foo2 _ -> 1 -- undefined<br />
<br />
-- The newtype behaves like Int, there is no<br />
-- constructor at runtime.<br />
y3 = case undefined of<br />
Foo3 _ -> 1 -- 1<br />
<br />
-- Demonstration of Int behavior<br />
int :: Int<br />
int = undefined<br />
<br />
yInt = case int of<br />
_ -> 1 -- 1<br />
</haskell><br />
<br />
== See also ==<br />
<br />
The Haskell 98 Report defines newtypes in [http://www.haskell.org/onlinereport/decls.html#sect4.2.3 section 4.2.3].<br />
<br />
[[Category:FAQ]]<br />
[[Category:Language]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=New_monads/MonadSupply&diff=42518
New monads/MonadSupply
2011-10-24T06:59:23Z
<p>CaleGibbard: </p>
<hr />
<div>[[Category:Code]]<br />
<br />
Here is a simple monad/monad transformer for computations which consume values from a (finite or infinite) supply. Note that due to pattern matching, running out of supply in a non-MonadZero monad will cause an error.<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts #-}<br />
<br />
module MonadSupply <br />
(SupplyT,<br />
MonadSupply,<br />
supply,<br />
Supply,<br />
evalSupplyT,<br />
evalSupply,<br />
runSupplyT,<br />
runSupply)<br />
where<br />
import Control.Monad<br />
import Control.Monad.State<br />
<br />
newtype SupplyT s m a = SupplyT (StateT [s] m a)<br />
deriving (Functor, Monad, MonadTrans, MonadIO)<br />
<br />
newtype Supply s a = Supply (SupplyT s Identity a)<br />
deriving (Functor, Monad, MonadSupply s)<br />
<br />
class Monad m => MonadSupply s m | m -> s where<br />
supply :: m s<br />
<br />
instance Monad m => MonadSupply s (SupplyT s m) where<br />
supply = SupplyT $ do<br />
(x:xs) <- get<br />
put xs<br />
return x<br />
<br />
evalSupplyT (SupplyT s) supp = evalStateT s supp<br />
evalSupply (Supply s) supp = evalSupplyT s supp<br />
<br />
runSupplyT (SupplyT s) supp = runStateT s supp<br />
runSupply (Supply s) supp = runSupplyT s supp<br />
</haskell><br />
<br />
As an example, if we want to supply unique strings for use as variable names, the following specialisation of runSupply (or its obvious analogue with runSupplyT) might be handy:<br />
<haskell><br />
runSupplyVars x = runSupply x vars<br />
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence<br />
</haskell></div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Monads_as_computation&diff=38964
Monads as computation
2011-03-13T01:14:15Z
<p>CaleGibbard: /* The whole point */</p>
<hr />
<div>=== Motivation ===<br />
<br />
Programmers in general, and functional programmers in particular, are usually not so content to solve a problem in a fragile way by coding a solution directly. Quite often the best way to solve a problem is to design a domain-specific language in which the solution to one's problem is easily expressed. Doing this generally ensures that a wide class of similar problems can be attacked using the same code. That way, you get code which is resistant to damage in the form of changes to design requirements.<br />
<br />
Better still, we'd like to embed those domain specific languages into the language which we wrote them in, so that they can be used together, and so we get benefits from the language we're working in without so much extra work. So we write combinator libraries which are essentially libraries of code whose API's are sufficiently powerful that using the library is like programming in a small language embedded within the existing one.<br />
<br />
Such a library will have some representation of primitive computations, and some ways to glue those computations together into more complex ones. A parsing library might define primitive parsers for parsing single characters, and then combining functions for concatenating parsers or selecting between them. A drawing library might define some basic drawing operations, and then various means of combining drawings into larger ones (on top, beside, above, etc.).<br />
<br />
In this manner, the user of the combinator library builds up the computation they want, piecing together smaller parts into larger ones.<br />
<br />
As far as programming is concerned, a [[monad]] is just a particular style of combinator library. That is, one which supports a few basic means of combination.<br />
<br />
The reason for making this abstraction is so that all the libraries which make use of those means of combination can then share a library of combining functions built up from the primitive ones they are required to support.<br />
<br />
Specifically, by defining an instance of Monad for your library when appropriate, you automatically get the benefit of the functions in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad library] (as well as a few others, like [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html Data.Traversable]). This includes things like for-each loops (forM/mapM), ways to turn pure functions into combiners (liftM2, etc.), as well as other control structures which you get for free just for making your library an instance of Monad.<br />
<br />
=== The parts of a monad ===<br />
<br />
There are of course, other kinds of combinator library, but monads arise fairly naturally from a few basic premises.<br />
<br />
* Monadic computations have results. This is reflected in the types. Given a monad M, a value of type <code>M t</code> is a computation resulting in a value of type <code>t</code>. It's important to realise that this is typically just some data structure. It will be interpreted as a computation and "run" in a way which is dependent on the given library.<br />
* For any value, there is a computation which "does nothing", and produces that result. This is given by defining the function <code>return</code> for the given monad.<haskell><br />
return :: (Monad m) => a -> m a<br />
</haskell><br />
* Given a pair of computations <hask>x</hask> and <hask>y</hask>, one can form the computation <hask>x >> y</hask>, which intuitively "runs" the computation <hask>x</hask>, throws away its result, then runs <hask>y</hask> returning its result.<haskell><br />
(>>) :: (Monad m) => m a -> m b -> m b<br />
</haskell><br />
* Further, we're allowed to use the result of the first computation to decide "what to do next", rather than just throwing it away. This idea is embodied by the operation <hask>(>>=)</hask>, called 'bind'. If <hask>x</hask> is a computation, and <hask>f</hask> is a function from potential results of that computation to further computations to be performed, then <hask>x >>= f</hask> is a computation which runs <hask>x</hask>, then applies <hask>f</hask> to its result, getting a computation which it then runs. The result of this latter computation is the result of the combined one.<haskell><br />
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b<br />
</haskell><br />
<br />
In fact, once we have bind, we can always define <hask>(>>)</hask> as:<br />
<haskell><br />
x >> y = x >>= (\_ -> y)<br />
</haskell><br />
<br />
It's important to realise that both what it means to "run" a computation, and what "then" means in the above are both <em>up to the monad in question</em> (subject to a few simple constraints to be discussed later). This point will become clearer as one sees more and more examples.<br />
<br />
=== A few examples ===<br />
<br />
On top of <hask>return</hask> and <hask>(>>=)</hask>, any given monad will typically define a bunch of primitive computations to get the user of the library started. The <hask>IO</hask> monad, for instance, has a large number of I/O operations such as <hask>getLine :: IO String</hask> and <hask>putStrLn :: String -> IO ()</hask>. The program: <haskell><br />
main :: IO ()<br />
main = getLine >>= putStrLn<br />
</haskell> gets a line of text from the user, and then prints it back out.<br />
For a slightly more complicated example, the program: <haskell><br />
main :: IO ()<br />
main = putStrLn "Enter a line of text:"<br />
>> getLine >>= \x -> putStrLn (reverse x)<br />
</haskell> prompts the user for a line of text, gets the line of text from the user, and then prints it back out in reverse.<br />
<br />
A parsing monad might define <hask>char :: Char -> Parser Char</hask>, for constructing a parser which succeeds if the input string matches the given character. As a very simple example without getting into the details of parsing monads, the parser: <haskell><br />
cat = char 'c' >> char 'a' >> char 't' >> return "It's a cat."<br />
</haskell> would try to match the string "cat", and if the parse succeeded, would return the string <hask>"It's a cat."</hask>.<br />
<br />
=== Do notation ===<br />
<br />
Because computations are typically going to be built up from long chains of <hask>(>>)</hask> and <hask>(>>=)</hask>, in Haskell, we have some syntax-sugar, called do-notation.<br />
<br />
The do-notation allows us to write our second IO program above as:<br />
<haskell><br />
main = do putStrLn "Enter a line of text:"<br />
x <- getLine<br />
putStrLn (reverse x)<br />
</haskell><br />
<br />
The basic mechanical translation for the do-notation is as follows:<br />
<haskell><br />
do { x } = x<br />
<br />
do { x ; <stmts> }<br />
= x >> do { <stmts> }<br />
<br />
do { v <- x ; <stmts> }<br />
= x >>= \v -> do { <stmts> }<br />
<br />
do { let <decls> ; <stmts> }<br />
= let <decls> in do { <stmts> }<br />
</haskell><br />
<br />
This gives monadic computations a bit of an imperative feel, but it's important to remember that the monad in question gets to decide what the combination means, and so some unusual forms of control flow might actually occur. In some monads (like parsers, or the list monad), "backtracking" may occur, and in others, even more exotic forms of control might show up (for instance, first-class continuations, or some form of parallelism).<br />
<br />
=== The monad laws ===<br />
<br />
However, in order to maintain some semblance of sanity, we agree to make the monads we define follow some basic rules. I'll show the three rules both in terms of <hask>return</hask> and <hask>(>>=)</hask> and do-notation, and try to give some feel of what they really mean.<br />
<br />
<haskell><br />
1. return v >>= f = f v<br />
<br />
2. x >>= return = x<br />
<br />
3. (x >>= f) >>= g = x >>= (\v -> f v >>= g)<br />
</haskell><br />
<br />
Rules 1 and 2 basically give one the sense that <hask>return v</hask> "does nothing" and results in <hask>v</hask>.<br />
<br />
Rule 3 puts a bit of a constraint on what "then" is supposed to mean. It is perhaps easier at first to look at what it means for <hask>(>>)</hask>:<br />
<haskell><br />
(x >> y) >> z = x >> (y >> z)<br />
</haskell><br />
This corresponds nicely with our usual reading of <hask>(>>)</hask> as "then":<br />
<br />
putting on your tie, <strong>then</strong> (putting on your socks <strong>then</strong> putting on your shoes)<br />
<br />
is the same thing as<br />
<br />
(putting on your tie <strong>then</strong> putting on your socks) <strong>then</strong> putting on your shoes.<br />
<br />
To get a bit of a different perspective on what the laws mean, let's see what they look like in do-notation:<br />
<br />
<haskell><br />
1. do { w <- return v; f w }<br />
= do { f v }<br />
<br />
2. do { v <- x; return v }<br />
= do { x }<br />
</haskell><br />
<br />
These two are again consistent with the idea that return produces a computation that has no "side-effects", and just returns its parameter.<br />
<br />
<haskell><br />
3. do w <- do v <- x<br />
f v<br />
g w<br />
<br />
= do v <- x<br />
w <- f v<br />
g w<br />
</haskell><br />
<br />
This is more interesting. It's telling us that asking for the result of a compound computation in the midst of a do-block will result in exactly the same thing as if that compound computation had been spliced in directly, and gives us a valid way to refactor code written in any monad. We're allowed to abstract a chunk of code out from the middle of a do-block and give it a name without worrying about whether we've changed the meaning of the code.<br />
<br />
=== The whole point ===<br />
<br />
This is all very good, but apart from defining a pretty syntax for a certain kind of combinator library, the stuff we've done so far is fairly inessential. What's the point of recognising something as a monad?<br />
<br />
The point, as I alluded to in the introduction, is that we can then write code which works for all monads, and have a whole library of code which is made available to us just for recognising that the library we're writing happens to be a monad. Since we have only return and bind to work with, this sort of code will serve to chain computations together in some methodical way. That is to say, it will consist of control structures.<br />
<br />
All the examples I'll give are already defined in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad] library, along with many more.<br />
<br />
The first example of such a control structure we'll look at is called <hask>sequence</hask>. It's a function which takes a list of computations of the same type, and builds from them a computation which will run each in turn and produce a list of the results:<br />
<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = do v <- x<br />
vs <- sequence xs<br />
return (v:vs)<br />
</haskell><br />
or, without the do-notation:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = x >>= \v -> sequence xs >>= \vs -> return (v:vs)<br />
</haskell><br />
(one can start to see why do-notation might be desirable!)<br />
<br />
In a parsing monad, we might pass it a list of parsers, and get back a parser which parses its input using each in turn. In the IO monad, a simple example might be the following:<br />
<haskell><br />
main = sequence [getLine, getLine] >>= print<br />
</haskell><br />
which gets two lines of text from the user, and then prints the list.<br />
<br />
Since lists are lazy in Haskell, this gives us a sort of primordial loop from which most other kinds of loops can be built.<br />
<br />
What is a for-each loop really? It's something which performs some action based on each element of a list. So we might imagine a function with the type:<br />
<haskell><br />
forM :: (Monad m) => [a] -> (a -> m b) -> m [b]<br />
</haskell><br />
(as an added bonus, we'll have it collect the results of each iteration).<br />
<br />
We can write this with sequence and map:<br />
<haskell><br />
forM xs f = sequence (map f xs)<br />
</haskell><br />
we apply the function to each element of the list to construct the action for that iteration, and then sequence the actions together into a single computation.<br />
<br />
For example:<br />
<haskell><br />
main = forM [1..10] $ \x -> do<br />
putStr "Looping: "<br />
print x<br />
</haskell><br />
<br />
Since in this, and many other cases, the loop body doesn't produce a particularly interesting result, there are variants of <hask>sequence</hask> and <hask>forM</hask> called <hask>sequence_</hask> and <hask>forM_</hask>, which simply throw the results away as they run each of the actions.<br />
<br />
<haskell><br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ [] = return ()<br />
sequence_ (x:xs) = x >> sequence_ xs<br />
<br />
forM_ :: (Monad m) => [a] -> (a -> m b) -> m ()<br />
forM_ xs f = sequence_ (map f xs)<br />
</haskell><br />
<br />
Sometimes we only want a computation to happen when a given condition is true. For this, we can write the following:<br />
<haskell><br />
when :: (Monad m) => Bool -> m () -> m ()<br />
when p x = if p then x else return ()<br />
</haskell><br />
Remember that <hask>return ()</hask> is a no-op, so running this computation will run x when the condition is true, and will do nothing at all when the condition fails.<br />
<br />
Another extremely common thing to do is to construct a computation which performs another computation and then applies a function to the result. This can be accomplished by using the <hask>liftM</hask> function:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = do v <- x<br />
return (f v)<br />
</haskell><br />
Or:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = return . f =<< x<br />
</haskell><br />
where <hask>(=<<)</hask> is just bind with its parameters flipped.<br />
<br />
This is also generalised by <hask>liftM2, liftM3, ...</hask> to running more than one computation before applying a function to the results:<br />
<haskell><br />
liftM2 :: (Monad m) => (a -> b -> c) -> m a -> m b -> m c<br />
liftM2 f x y = do v <- x<br />
w <- y<br />
return (f v w)<br />
</haskell><br />
<br />
It's possible to rewrite sequence in terms of liftM2, return, and a fold over the list:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence xs = foldr (liftM2 (:)) (return []) xs<br />
<br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ xs = foldr (>>) (return ()) xs<br />
</haskell><br />
<br />
Anyway, these are just a few of the simpler examples to give a taste of what sorts of control structures you get for free by defining a combinator library as a monad.<br />
<br />
=== Some final notes ===<br />
<br />
It's a common misconception that Haskell uses a monad for I/O out of necessity. Really, it could use any sort of combinator library to describe and combine I/O actions. It just happens that the most obvious way to formulate a library to describe I/O actions ends up being a monad. So we define it as such so as to be able to share all these control structures with other monadic libraries.<br />
<br />
That's really the only reason why we ever define anything as a monad -- the abstraction allows us to make use of a bunch of shared code for free without writing it out over and over again (or worse yet, failing to abstract it at all).<br />
<br />
At this point, you might want to look at some more examples of monads. One place which is a decent starting point for that is Part II of the [http://horna.org.ua/books/All_About_Monads.pdf "All About Monads" tutorial]. You might also have a look at the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Hierarchical Libraries Documentation] for the libraries under Control.Monad.<br />
<br />
-- [[User:CaleGibbard|CaleGibbard]]<br />
<br />
[[Category:Tutorials]] [[Category:Monad]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Template:Main/Intro&diff=37680
Template:Main/Intro
2010-12-02T03:32:47Z
<p>CaleGibbard: </p>
<hr />
<div>Haskell is an advanced [[functional programming|purely-functional]]<br />
programming language. An open-source product of more than twenty years of cutting-edge research, <br />
it allows rapid development of robust, concise, correct<br />
software. With strong support for [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ integration with other languages],<br />
built-in [http://haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism concurrency and parallelism], debuggers, profilers, [http://hackage.haskell.org/packages/hackage.html rich libraries] and an active community, Haskell makes it easier to produce flexible, maintainable, <br />
high-quality software.</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Template:Main/Intro&diff=37679
Template:Main/Intro
2010-12-02T03:31:47Z
<p>CaleGibbard: </p>
<hr />
<div>Haskell is an advanced [[functional programming|purely-functional]]<br />
programming language. An open source product of more than twenty years of cutting edge research, <br />
it allows rapid development of robust, concise, correct<br />
software. With strong support for [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ integration with other languages],<br />
built-in [http://haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism concurrency and parallelism], debuggers, profilers, [http://hackage.haskell.org/packages/hackage.html rich libraries] and an active community, Haskell makes it easier to produce flexible, maintainable <br />
high-quality software.</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Monads_as_computation&diff=37415
Monads as computation
2010-11-08T20:22:37Z
<p>CaleGibbard: </p>
<hr />
<div>=== Motivation ===<br />
<br />
Programmers in general, and functional programmers in particular, are usually not so content to solve a problem in a fragile way by coding a solution directly. Quite often the best way to solve a problem is to design a domain-specific language in which the solution to one's problem is easily expressed. Doing this generally ensures that a wide class of similar problems can be attacked using the same code. That way, you get code which is resistant to damage in the form of changes to design requirements.<br />
<br />
Better still, we'd like to embed those domain specific languages into the language which we wrote them in, so that they can be used together, and so we get benefits from the language we're working in without so much extra work. So we write combinator libraries which are essentially libraries of code whose API's are sufficiently powerful that using the library is like programming in a small language embedded within the existing one.<br />
<br />
Such a library will have some representation of primitive computations, and some ways to glue those computations together into more complex ones. A parsing library might define primitive parsers for parsing single characters, and then combining functions for concatenating parsers or selecting between them. A drawing library might define some basic drawing operations, and then various means of combining drawings into larger ones (on top, beside, above, etc.).<br />
<br />
In this manner, the user of the combinator library builds up the computation they want, piecing together smaller parts into larger ones.<br />
<br />
As far as programming is concerned, a [[monad]] is just a particular style of combinator library. That is, one which supports a few basic means of combination.<br />
<br />
The reason for making this abstraction is so that all the libraries which make use of those means of combination can then share a library of combining functions built up from the primitive ones they are required to support.<br />
<br />
Specifically, by defining an instance of Monad for your library when appropriate, you automatically get the benefit of the functions in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad library] (as well as a few others, like [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html Data.Traversable]). This includes things like for-each loops (forM/mapM), ways to turn pure functions into combiners (liftM2, etc.), as well as other control structures which you get for free just for making your library an instance of Monad.<br />
<br />
=== The parts of a monad ===<br />
<br />
There are of course, other kinds of combinator library, but monads arise fairly naturally from a few basic premises.<br />
<br />
* Monadic computations have results. This is reflected in the types. Given a monad M, a value of type <code>M t</code> is a computation resulting in a value of type <code>t</code>. It's important to realise that this is typically just some data structure. It will be interpreted as a computation and "run" in a way which is dependent on the given library.<br />
* For any value, there is a computation which "does nothing", and produces that result. This is given by defining the function <code>return</code> for the given monad.<haskell><br />
return :: (Monad m) => a -> m a<br />
</haskell><br />
* Given a pair of computations <hask>x</hask> and <hask>y</hask>, one can form the computation <hask>x >> y</hask>, which intuitively "runs" the computation <hask>x</hask>, throws away its result, then runs <hask>y</hask> returning its result.<haskell><br />
(>>) :: (Monad m) => m a -> m b -> m b<br />
</haskell><br />
* Further, we're allowed to use the result of the first computation to decide "what to do next", rather than just throwing it away. This idea is embodied by the operation <hask>(>>=)</hask>, called 'bind'. If <hask>x</hask> is a computation, and <hask>f</hask> is a function from potential results of that computation to further computations to be performed, then <hask>x >>= f</hask> is a computation which runs <hask>x</hask>, then applies <hask>f</hask> to its result, getting a computation which it then runs. The result of this latter computation is the result of the combined one.<haskell><br />
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b<br />
</haskell><br />
<br />
In fact, once we have bind, we can always define <hask>(>>)</hask> as:<br />
<haskell><br />
x >> y = x >>= (\k -> y)<br />
</haskell><br />
<br />
It's important to realise that both what it means to "run" a computation, and what "then" means in the above are both <em>up to the monad in question</em> (subject to a few simple constraints to be discussed later). This point will become clearer as one sees more and more examples.<br />
<br />
=== A few examples ===<br />
<br />
On top of <hask>return</hask> and <hask>(>>=)</hask>, any given monad will typically define a bunch of primitive computations to get the user of the library started. The <hask>IO</hask> monad, for instance, has a large number of I/O operations such as <hask>getLine :: IO String</hask> and <hask>putStrLn :: String -> IO ()</hask>. The program: <haskell><br />
main :: IO ()<br />
main = getLine >>= putStrLn<br />
</haskell> gets a line of text from the user, and then prints it back out.<br />
For a slightly more complicated example, the program: <haskell><br />
main :: IO ()<br />
main = putStrLn "Enter a line of text:"<br />
>> getLine >>= \x -> putStrLn (reverse x)<br />
</haskell> prompts the user for a line of text, gets the line of text from the user, and then prints it back out in reverse.<br />
<br />
A parsing monad might define <hask>char :: Char -> Parser Char</hask>, for constructing a parser which succeeds if the input string matches the given character. As a very simple example without getting into the details of parsing monads, the parser: <haskell><br />
cat = char 'c' >> char 'a' >> char 't' >> return "It's a cat."<br />
</haskell> would try to match the string "cat", and if the parse succeeded, would return the string <hask>"It's a cat."</hask>.<br />
<br />
=== Do notation ===<br />
<br />
Because computations are typically going to be built up from long chains of <hask>(>>)</hask> and <hask>(>>=)</hask>, in Haskell, we have some syntax-sugar, called do-notation.<br />
<br />
The do-notation allows us to write our second IO program above as:<br />
<haskell><br />
main = do putStrLn "Enter a line of text:"<br />
x <- getLine<br />
putStrLn (reverse x)<br />
</haskell><br />
<br />
The basic mechanical translation for the do-notation is as follows:<br />
<haskell><br />
do { x } = x<br />
<br />
do { x ; <stmts> }<br />
= x >> do { <stmts> }<br />
<br />
do { v <- x ; <stmts> }<br />
= x >>= \v -> do { <stmts> }<br />
<br />
do { let <decls> ; <stmts> }<br />
= let <decls> in do { <stmts> }<br />
</haskell><br />
<br />
This gives monadic computations a bit of an imperative feel, but it's important to remember that the monad in question gets to decide what the combination means, and so some unusual forms of control flow might actually occur. In some monads (like parsers, or the list monad), "backtracking" may occur, and in others, even more exotic forms of control might show up (for instance, first-class continuations, or some form of parallelism).<br />
<br />
=== The monad laws ===<br />
<br />
However, in order to maintain some semblance of sanity, we agree to make the monads we define follow some basic rules. I'll show the three rules both in terms of <hask>return</hask> and <hask>(>>=)</hask> and do-notation, and try to give some feel of what they really mean.<br />
<br />
<haskell><br />
1. return v >>= f = f v<br />
<br />
2. x >>= return = x<br />
<br />
3. (x >>= f) >>= g = x >>= (\v -> f v >>= g)<br />
</haskell><br />
<br />
Rules 1 and 2 basically give one the sense that <hask>return v</hask> "does nothing" and results in <hask>v</hask>.<br />
<br />
Rule 3 puts a bit of a constraint on what "then" is supposed to mean. It is perhaps easier at first to look at what it means for <hask>(>>)</hask>:<br />
<haskell><br />
(x >> y) >> z = x >> (y >> z)<br />
</haskell><br />
This corresponds nicely with our usual reading of <hask>(>>)</hask> as "then":<br />
<br />
putting on your tie, <strong>then</strong> (putting on your socks <strong>then</strong> putting on your shoes)<br />
<br />
is the same thing as<br />
<br />
(putting on your tie <strong>then</strong> putting on your socks) <strong>then</strong> putting on your shoes.<br />
<br />
To get a bit of a different perspective on what the laws mean, let's see what they look like in do-notation:<br />
<br />
<haskell><br />
1. do { w <- return v; f w }<br />
= do { f v }<br />
<br />
2. do { v <- x; return v }<br />
= do { x }<br />
</haskell><br />
<br />
These two are again consistent with the idea that return produces a computation that has no "side-effects", and just returns its parameter.<br />
<br />
<haskell><br />
3. do w <- do v <- x<br />
f v<br />
g w<br />
<br />
= do v <- x<br />
w <- f v<br />
g w<br />
</haskell><br />
<br />
This is more interesting. It's telling us that asking for the result of a compound computation in the midst of a do-block will result in exactly the same thing as if that compound computation had been spliced in directly, and gives us a valid way to refactor code written in any monad. We're allowed to abstract a chunk of code out from the middle of a do-block and give it a name without worrying about whether we've changed the meaning of the code.<br />
<br />
=== The whole point ===<br />
<br />
This is all very good, but apart from defining a pretty syntax for a certain kind of combinator library, the stuff we've done so far is fairly inessential. What's the point of recognising something as a monad?<br />
<br />
The point, as I alluded to in the introduction, is that we can then write code which works for all monads, and have a whole library of code which is made available to us just for recognising that the library we're writing happens to be a monad. Since we have only return and bind to work with, this sort of code will serve to chain computations together in some methodical way. That is to say, it will consist of control structures.<br />
<br />
All the examples I'll give are already defined in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad] library, along with many more.<br />
<br />
The first example of such a control structure we'll look at is called <hask>sequence</hask>. It's a function which takes a list of computations of the same type, and builds from them a computation which will run each in turn and produce a list of the results:<br />
<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = do v <- x<br />
vs <- sequence xs<br />
return (v:vs)<br />
</haskell><br />
or, without the do-notation:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = x >>= \v -> sequence xs >>= \vs -> return (v:vs)<br />
</haskell><br />
(one can start to see why do-notation might be desirable!)<br />
<br />
In a parsing monad, we might pass it a list of parsers, and get back a parser which parses its input using each in turn. In the IO monad, a simple example might be the following:<br />
<haskell><br />
main = sequence [getLine, getLine] >>= print<br />
</haskell><br />
which gets two lines of text from the user, and then prints the list.<br />
<br />
Since lists are lazy in Haskell, this gives us a sort of primordial loop from which most other kinds of loops can be built.<br />
<br />
What is a for-each loop really? It's something which performs some action based on each element of a list. So we might imagine a function with the type:<br />
<haskell><br />
forM :: (Monad m) => [a] -> (a -> m b) -> m [b]<br />
</haskell><br />
(as an added bonus, we'll have it collect the results of each iteration).<br />
<br />
We can write this with sequence and map:<br />
<haskell><br />
forM xs f = sequence (map f xs)<br />
</haskell><br />
we apply the function to each element of the list to construct the action for that iteration, and then sequence the actions together into a single computation.<br />
<br />
For example:<br />
<haskell><br />
main = forM [1..10] $ \x -> do<br />
putStr "Looping: "<br />
print x<br />
</haskell><br />
<br />
Since in this, and many other cases, the loop body doesn't produce a particularly interesting result, there are variants of <hask>sequence</hask> and <hask>forM</hask> called <hask>sequence_</hask> and <hask>forM_</hask>, which simply throw the results away as they run each of the actions.<br />
<br />
<haskell><br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ [] = return ()<br />
sequence_ (x:xs) = x >> sequence xs<br />
<br />
forM_ :: (Monad m) => [a] -> (a -> m b) -> m ()<br />
forM_ xs f = sequence_ (map f xs)<br />
</haskell><br />
<br />
Sometimes we only want a computation to happen when a given condition is true. For this, we can write the following:<br />
<haskell><br />
when :: (Monad m) => Bool -> m () -> m ()<br />
when p x = if p then x else return ()<br />
</haskell><br />
Remember that <hask>return ()</hask> is a no-op, so running this computation will run x when the condition is true, and will do nothing at all when the condition fails.<br />
<br />
Another extremely common thing to do is to construct a computation which performs another computation and then applies a function to the result. This can be accomplished by using the <hask>liftM</hask> function:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = do v <- x<br />
return (f v)<br />
</haskell><br />
Or:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = return . f =<< x<br />
</haskell><br />
where <hask>(=<<)</hask> is just bind with its parameters flipped.<br />
<br />
This is also generalised by <hask>liftM2, liftM3, ...</hask> to running more than one computation before applying a function to the results:<br />
<haskell><br />
liftM2 :: (Monad m) => (a -> b -> c) -> m a -> m b -> m c<br />
liftM2 f x y = do v <- x<br />
w <- y<br />
return (f v w)<br />
</haskell><br />
<br />
It's possible to rewrite sequence in terms of liftM2, return, and a fold over the list:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence xs = foldr (liftM2 (:)) (return []) xs<br />
<br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ xs = foldr (>>) (return ()) xs<br />
</haskell><br />
<br />
Anyway, these are just a few of the simpler examples to give a taste of what sorts of control structures you get for free by defining a combinator library as a monad.<br />
<br />
=== Some final notes ===<br />
<br />
It's a common misconception that Haskell uses a monad for I/O out of necessity. Really, it could use any sort of combinator library to describe and combine I/O actions. It just happens that the most obvious way to formulate a library to describe I/O actions ends up being a monad. So we define it as such so as to be able to share all these control structures with other monadic libraries.<br />
<br />
That's really the only reason why we ever define anything as a monad -- the abstraction allows us to make use of a bunch of shared code for free without writing it out over and over again (or worse yet, failing to abstract it at all).<br />
<br />
At this point, you might want to look at some more examples of monads. One place which is a decent starting point for that is [http://www.haskell.org/all_about_monads/html/introII.html Part II of the "All About Monads" tutorial]. You might also have a look at the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Hierarchical Libraries Documentation] for the libraries under Control.Monad.<br />
<br />
-- [[User:CaleGibbard|CaleGibbard]]<br />
<br />
[[Category:Tutorials]] [[Category:Monad]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Web/Literature/Practical_web_programming_in_Haskell&diff=36531
Web/Literature/Practical web programming in Haskell
2010-08-18T09:04:36Z
<p>CaleGibbard: Switch from chained $ to compositional style</p>
<hr />
<div>[[Category:Tutorials]]<br />
[[Category:Web]]<br />
{{Template:Formal under construction}}<br />
<br />
'''NOTE: I believe a lot of the information on this page is dated, and will lead beginners in the wrong direction. I've begun documenting some of the more modern options for Haskell web development on the [[Web]] page of this wiki. -- Michael Snoyman'''<br />
<br />
<br />
== Introduction ==<br />
<br />
This tutorial aims to get you started with writing web applications<br />
in Haskell. We describe a relatively light-weight <br />
approach to Haskell web programming<br />
which uses a CGI library and an XHTML combinator library. <br />
<br />
We think that while the approach we describe here is not as sophisticated<br />
or innovative as some other approaches, it is simple, portable and easy<br />
to understand if you are already familiar with web programming in other <br />
languages.<br />
<br />
The tutorial starts with preliminaries such as how to install the<br />
necessary software and how to compile and run your web<br />
applications. We then show a number of working small example programs<br />
which introduce the basic features of the CGI and XHtml libraries. We<br />
then move on to how to use monad transformers to add application<br />
specific functionality such as sessions to the CGI monad, and how to<br />
create database-driven web applications.<br />
We also present FastCGI, and an approach to using dynamically<br />
loaded Haskell code.<br />
<br />
<br />
=== Other approaches ===<br />
<br />
[Web Authoring System Haskell <br />
(WASH) [http://www.informatik.uni-freiburg.de/~thiemann/WASH/].<br />
Domain-specific embedded language. Type-safe forms handling. <br />
Threads continuation through client. This gives good<br />
back-button and session splitting properties.<br />
<br />
Haskell Application Server <br />
(HAppS) [http://happs.org/].<br />
Complete system including web server in one program.<br />
Uses XSLT for output.<br />
<br />
[http://www.happstack.com Happstack] is the successor to HAppS. It is a complete system including a web server and datatbase system in one program. It has many template options including HSP, HStringTemplate, Hamlet, XSLT, and more!<br />
<br />
Haskell Server Pages <br />
(HSP) [http://www.cs.chalmers.se/~d00nibro/hsp/].<br />
Uses preprocessor to make XML tags into Haskell expressions.<br />
Dynamic compilation.<br />
<br />
<br />
=== Assumed knowledge ===<br />
<br />
This tutorial is not meant as an introduction to Haskell or web programming.<br />
We will assume that you have some familiarity with the following <br />
concepts:<br />
<br />
<br />
==== Haskell ====<br />
<br />
This tutorial is not meant as a first introduction to Haskell. If you<br />
want to learn about Haskell in general, have a look at the lists of <br />
[[books and tutorials]]. You may want to start with [[Haskell in 5 steps]].<br />
<br />
<br />
==== (X)HTML ====<br />
<br />
[http://www.w3.org/MarkUp/ HTML (HyperText Markup Language)] is the <br />
"the lingua franca for publishing hypertext on the World Wide Web''.<br />
The XHtml library which we use in this tutorial produces <br />
[http://www.w3.org/TR/xhtml1/ XHTML 1.0], which is <br />
[http://www.w3.org/TR/html401/ HTML 4.0] formulated as <br />
[http://www.w3.org/XML/ XML].<br />
<br />
The combinators in the XHtml library do not make much sense unless you<br />
understand at least some parts of HTML. <br />
<br />
<br />
==== CGI ====<br />
<br />
CGI (Common Gateway Interface) programs are programs which run on the<br />
web server. They are given input which comes from the user's browser, <br />
and their output is given to the browser.<br />
<br />
To really understand how the CGI library works, you probably need to know<br />
a thing or two about CGI. ([http://www.comp.leeds.ac.uk/Perl/Cgi/start.html Tutorial].) <br />
The authoritative resource on CGI is the<br />
[http://hoohoo.ncsa.illinois.edu/cgi/interface.html CGI specification].<br />
<br />
<br />
== Required software ==<br />
<br />
=== Haskell compiler ===<br />
<br />
[[GHC]], the Glasgow Haskell <br />
Compiler, is the Haskell implementation that we will use in this tutorial. <br />
However, any Haskell implementation that supports Haskell98 and multi-parameter<br />
type classes should work.<br />
<br />
<br />
=== Libraries: xhtml and cgi ===<br />
<br />
If your Haskell implementation does not come with the <tt>xhtml</tt> and<br />
<tt>cgi</tt> packages, download them from <br />
[http://hackage.haskell.org/packages/hackage.html HackageDB].<br />
<br />
<br />
=== Web server ===<br />
<br />
You need to have access to a web server on which you can run CGI programs.<br />
The most convenient way to do this when learning and developing is to run<br />
a web server on your development machine. If you run the programs on some<br />
other machine you need to make sure that you compile your programs <br />
so that they can run on that machine. This normally means that the machines<br />
must to have the same architecture and run the same operating system. <br />
<br />
<br />
====Deploying statically linked applications ====<br />
<br />
Linking your applications statically by giving the flags <tt>-static<br />
-optl-static</tt> to GHC will avoid problems with missing libraries on<br />
the web server.<br />
<br />
For example, this simple program,<br />
<br />
<haskell><br />
import Database.SQLite<br />
main = print "hey, test this"<br />
</haskell><br />
<br />
when compiled as $ ghc A.hs --make is dynamically linked against:<br />
<br />
<haskell><br />
$ ldd A<br />
A:<br />
Start End Type Open Ref GrpRef Name<br />
0000000000000000 0000000000000000 exe 1 0 0 A<br />
0000000041a85000 0000000041ee5000 rlib 0 1 0 /usr/local/lib/libsqlite3.so.9.0<br />
0000000049b04000 0000000049f1d000 rlib 0 1 0 /usr/lib/libm.so.2.3<br />
0000000042213000 000000004264f000 rlib 0 1 0 /usr/local/lib/libgmp.so.7.0<br />
0000000047d0e000 00000000481e0000 rlib 0 1 0 /usr/lib/libc.so.42.0<br />
0000000047900000 0000000047900000 rtld 0 1 0 /usr/libexec/ld.so<br />
</haskell><br />
<br />
Now, we can just pass some linker flags through to statically link this lot,<br />
<br />
<haskell><br />
$ ghc A.hs --make -optl-static -no-recomp<br />
$ ldd A<br />
ldd: A: not a dynamic executable<br />
$ file A<br />
A: ELF 64-bit LSB executable, AMD64, version 1, for OpenBSD, statically linked, not stripped<br />
</haskell><br />
<br />
You could also use the [[Haskell Web Server]].<br />
<br />
'''Caveats:'''<br />
<br />
* The <tt>-static</tt> flag in GHC 6.8.2 does not link the libraries in the correct order, resulting in a link failure (which you can hack around if you have to by shuffling <tt>-lpthread</tt> after <tt>-lrt</tt> in the gargantuan linker invocation). This problem should disappear with GHC 6.8.3.<br />
* Sometimes you will need to add <tt>extra-libraries</tt> fields to various libraries' <tt>.cabal</tt> files. This manifests as missing symbols. Note that many linkers are sensitive to the order of the <tt>-l</tt> arguments, so the order of libraries in this field matters.<br />
<br />
<br />
== Compiling and running web applications ==<br />
<br />
Use GHC to produce a binary executable called <tt>prog.cgi</tt> from the Haskell <br />
source code file <tt>prog.hs</tt>:<br />
<pre><br />
ghc --make -package cgi -package xhtml -o prog.cgi prog.hs<br />
</pre><br />
<br />
Put the compiled program in the cgi-bin directory,<br />
or give it the extension .cgi, depending on the configuration<br />
of the web server.<br />
<br />
Linking your applications statically <br />
by giving the flags <tt>-static -optl-static</tt> to GHC <br />
will avoid problems with missing libraries on the web server.<br />
<br />
To run the compiled program, visit the URL of the CGI <br />
program with your web browser.<br />
<br />
<br />
== Simple examples ==<br />
<br />
=== Hello World ===<br />
<br />
Here is a very simple example which just outputs some static HTML.<br />
The type signatures in this code are optional. We show them here <br />
for clarity, but omit them in some later examples.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
page :: Html <br />
page = body << h1 << "Hello World!"<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = output $ renderHtml page<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
The <code>page</code> function constructs an HTML document which consists<br />
of a body containing a single header element which contains the text<br />
"Hello World". The CGI-action <code>cgiMain</code> renders the HTML document<br />
as a string, and produces that string as output. The <code>main</code> function<br />
runs <code>cgiMain</code>, using the normal CGI protocol for input and output.<br />
It also uses <code>handleErrors</code> to output an error page in case |cgiMain|<br />
throws an exception.<br />
<br />
Fans of one-liners may like this version better (<code>handleErrors</code> has been <br />
omitted since this simple program will not throw any exceptions):<br />
<br />
<haskell><br />
import Text.XHtml<br />
import Network.CGI<br />
<br />
main = runCGI . output . renderHtml $ body << h1 << "Hello World!"<br />
</haskell><br />
<br />
These are some of the important functions used in this example:<br />
<br />
<haskell><br />
-- creates a string containing the HTML document.<br />
renderHtml :: Html -> String<br />
<br />
-- outputs a string as the body of the HTTP response.<br />
output :: String -> CGI CGIResult<br />
<br />
-- Catches any exception thrown by the given CGI action, returns an <br />
-- error page with a 500 Internal Server Error, showing the exception <br />
-- information, and logs the error.<br />
handleErrors :: CGI CGIResult -> CGI CGIResult<br />
<br />
-- Runs a CGI action which produces a CGIResult, using the CGI protocol<br />
-- to get the inputs and send the outputs.<br />
runCGI :: CGI CGIResult -> IO ()<br />
</haskell><br />
<br />
<br />
==== HTML combinators ====<br />
<br />
See also [http://cpansearch.perl.org/src/AUTRIJUS/Language-Haskell-0.01/hugs98-Nov2003/fptools/hslibs/text/html/doc/doc.htm].<br />
<br />
<code>Html</code> is the type of HTML fragments. It comes from the <code>Text.XHtml</code> module.<br />
There are functions for all XHTML 1.0 elements. <br />
Some examples:<br />
<br />
* header, body<br />
* h1, h2, ...<br />
* thediv<br />
* p<br />
* image<br />
<br />
The <code><<</code> operator is used for nesting HTML.<br />
<br />
<code>+++</code> concatenates HTML.<br />
<br />
Attributes are added to tags using the <code>!</code> operator.<br />
<br />
The function <code>renderHtml</code> (FIXME: explain variants) produces a string containing the<br />
document.<br />
<br />
<br />
=== Getting user input ===<br />
<br />
This program shows a form which asks the user for her name.<br />
When the form is submitted, the program greets the user by name.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
inputForm = form << [paragraph << ("My name is " +++ textfield "name"),<br />
submit "" "Submit"]<br />
<br />
greet n = paragraph << ("Hello " ++ n ++ "!")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain = do mn <- getInput "name"<br />
let x = maybe inputForm greet mn<br />
output . renderHtml $ page "Input example" x<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
This code makes use of the getInput function from the CGI library:<br />
<br />
<haskell><br />
-- Get the value of an input variable, for example from a form. <br />
-- If the variable has multiple values, the first one is returned.<br />
getInput :: String -> CGI (Maybe String)<br />
</haskell><br />
<br />
<br />
=== Cookies ===<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromMaybe)<br />
<br />
hello :: Int -> Html<br />
hello 0 = h1 << "Welcome!"<br />
+++ p << "This is the first time I see you."<br />
hello c = h1 << "Welcome back!"<br />
+++ p << ("I have seen you " ++ show c ++ " times before.")<br />
<br />
page :: String -> Html -> Html<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = do c <- liftM (fromMaybe 0) $ readCookie "mycookie"<br />
setCookie (newCookie "mycookie" (show (c+1)))<br />
output . renderHtml . page "Cookie example" $ hello c<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
Here we use <code>newCookie</code>, <code>setCookie</code> and <code>readCookie</code> to store and retrieve a counter<br />
cookie in the browser. If you want to get the string value of a cookie, use <code>getCookie</code> instead of <code>readCookie</code>.<br />
<br />
<br />
=== File uploads ===<br />
<br />
FIXME: use a safer example<br />
<br />
<haskell><br />
-- Accepts file uploads and saves the files in the given directory.<br />
-- WARNING: this script is a SECURITY RISK and only for <br />
-- demo purposes. Do not put it on a public web server.<br />
<br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import qualified Data.ByteString.Lazy as BS<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromJust)<br />
<br />
uploadDir = "../upload"<br />
<br />
fileForm = form ! [method "post", enctype "multipart/form-data"]<br />
<< [afile "file", submit "" "Upload"]<br />
saveFile n =<br />
do cont <- liftM fromJust $ getInputFPS "file"<br />
let f = uploadDir ++ "/" ++ basename n<br />
liftIO $ BS.writeFile f cont<br />
return $ paragraph << ("Saved as " +++ anchor ! [href f] << f +++ ".")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
basename = reverse . takeWhile (`notElem` "/\\") . reverse<br />
<br />
cgiMain = <br />
do mn <- getInputFilename "file"<br />
h <- maybe (return fileForm) saveFile mn<br />
output . renderHtml $ page "Upload example" h<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
We first output a file upload form, which should use the HTTP POST method, <br />
and the multipart/form-data content type. Here we seen an example of the use of<br />
HTML attributes, added with the <code>!</code> operator.<br />
<br />
For efficiency reasons, we use Data.ByteString.Lazy to represent the file contents.<br />
getInputFPS gets the value of an input variable as a lazy ByteString.<br />
<br />
<br />
=== Error handling ===<br />
<br />
handleErrors catches all exceptions and <br />
outputs a default error page with some information about the exception.<br />
You can write you own exception handler if you want to do something else<br />
when an exception is thrown. It can be useful to set<br />
the response code, e.g. 404.<br />
<br />
<br />
=== Returning non-HTML ===<br />
<br />
Of course we do not have to output HTML. Use setHeader to set the value<br />
of the Content-type header, and you can output whatever string you like. <br />
<br />
In this example we return an image:<br />
<br />
<haskell><br />
import Network.CGI<br />
import System.IO<br />
import qualified Data.ByteString.Lazy as B<br />
<br />
main = do<br />
b <- B.readFile "./img/test.jpg" -- read the image<br />
runCGI . handleErrors . cgiMain $ b<br />
<br />
cgiMain :: B.ByteString -> CGI CGIResult<br />
cgiMain p = do<br />
-- we need to set the appropriate content-type<br />
setHeader "Content-type" "image/jpg"<br />
outputFPS p<br />
</haskell><br />
<br />
Examples: RSS<br />
<br />
<br />
=== Setting response headers ===<br />
<br />
You can use the <code>setHeader</code> function to set arbitrary HTTP response headers.<br />
You can also set the response code, as seen above.<br />
<br />
Example: output raw file data (with last-modified)<br />
<br />
<br />
== Going further ==<br />
<br />
This section explores some of possibilities beyond the basic web application<br />
programming.<br />
<br />
<br />
=== Extending the CGI monad with monad transformers ===<br />
<br />
At this point, you should be able to create many useful CGI scripts.<br />
As your scripts get more ambitious, however, you may find yourself<br />
needing to pass "global" parameters to your CGI actions (e.g. database<br />
connections, session information.) Rather than explicitly passing<br />
these values around, you can extend the CGI monad to do this work for<br />
you.<br />
<br />
The <hask>Network.CGI.Monad</hask> module defines a CGI monad<br />
transformer, allowing us to build a new monad that does everything the<br />
CGI monad does -- and more!<br />
<br />
For example, let's define a new CGI monad that provides a database<br />
connection (in this example, we use the<br />
<hask>Database.HSQL.PostgreSQL</hask> module for our database.) Since<br />
it will be used by the CGI application, I'll call the new monad "App".<br />
<br />
Should this not compile for you, you need to enable some extensions:<br />
<haskell><br />
{-# LANGUAGE GeneralizedNewtypeDeriving #-}<br />
{-# LANGUAGE FlexibleInstances #-}<br />
</haskell><br />
<br />
After importing the appropriate modules, we define a new type,<br />
<hask>AppT</hask> that is made up of two monad transformers,<br />
<hask>CGIT</hask> and <hask>ReaderT</hask>. The <hask>CGIT</hask><br />
monad "wraps" the base monad "m". The <hask>CGIT</hask> monad, in<br />
turn, is wrapped by the <hask>ReaderT</hask> monad, which contains, in<br />
its environment, the database <hask>Connection</hask>.<br />
<br />
<hask>AppT</hask> takes two type parameters. The first is the base<br />
monad that the monad transformers are modifying. Usually this will be<br />
the <hask>IO</hask> monad. The second type is the data type that an<br />
action in the monad will return.<br />
<br />
<haskell><br />
import Control.Monad.Reader<br />
import Network.CGI<br />
import Network.CGI.Monad<br />
import Database.HSQL.PostgreSQL<br />
<br />
newtype AppT m a = App (ReaderT Connection (CGIT m) a)<br />
deriving (Monad, MonadIO, MonadReader Connection)<br />
</haskell><br />
<br />
Like <hask>CGI</hask>, we make a type synonym that defines the most<br />
common use of this new monad.<br />
<br />
<haskell><br />
type App a = AppT IO a<br />
</haskell><br />
<br />
We're not quite finished defining <hask>App</hask> yet. In order to be<br />
used like the CGI monad, <hask>App</hask> needs to be an instance of<br />
the <hask>MonadCGI</hask> class. This class defines two functions that<br />
we must support.<br />
<br />
<haskell><br />
instance MonadCGI (AppT IO) where<br />
cgiAddHeader n v = App . lift $ cgiAddHeader n v<br />
cgiGet x = App . lift $ cgiGet x<br />
</haskell><br />
<br />
So now we have an App monad that gives us all the functionality of<br />
CGI, but also carries around a database connection. The last step is<br />
to define the function that creates the monad so we can run actions<br />
inside it.<br />
<br />
<haskell><br />
import Control.Exception (bracket)<br />
import System.IO (stdin, stdout)<br />
<br />
runApp :: App CGIResult -> IO ()<br />
runApp (App a) =<br />
bracket (connect "host" "db" "user" "password")<br />
disconnect<br />
(\c -> do { env <- getCGIVars<br />
; hRunCGI env stdin stdout (runCGIT (runReaderT a c))<br />
; return () } )<br />
</haskell><br />
<br />
(either fill in your account/password information, or change<br />
<hask>runApp</hask> to accept the parameters as function arguments.)<br />
The function uses <hask>bracket</hask> so that the database connection<br />
gets released properly when the monad ends or if an exception is<br />
thrown.<br />
<br />
<br />
=== Templating ===<br />
<br />
There are times when you absolutely do not want to embed (X)HTML in Haskell. You can separate the code and the presentation (the Holy Grail of erm, web development). The code will be, well, Haskell, and the presentation will be buried inside templates. This might not be the case: fortunately, there is a very nice templating engine available: [[HStringTemplate]]; also very useful is [http://hackage.haskell.org/package/hakyll hakyll], a simple static site generator library, mainly aimed at creating blogs and brochure sites.<br />
<br />
<br />
=== FastCGI ===<br />
<br />
[http://www.fastcgi.com/ FastCGI] is a standard for CGI-like programs that are not restarted<br />
for every request. This reduces the overhead involved in handling each <br />
request, and reduces the servers response time for each request.<br />
The overhead involved in starting a new process for each<br />
request can also include the need to set up new DB connections <br />
every time. With FastCGI, DB connections can be reused.<br />
<br />
Install FastCGI. Get a web server which can run FastCGI programs.<br />
Import Network.FastCGI. Use runFastCGI.<br />
<br />
See also a tutorial by Paul R Brown: [http://mult.ifario.us/p/wiring-haskell-into-a-fastcgi-web-server Wiring Haskell Into a FastCGI Web Server]<br />
<br />
Take a look at lightweight, minimalistic FastCGI-based web frameworks: [http://community.haskell.org/~sclv/hvac/ HVAC] (Haskell view and controller) and [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/kibro Kibro].<br />
<br />
<br />
=== SCGI ===<br />
<br />
[http://www.mems-exchange.org/software/scgi/ SCGI] is a simpler alternative to FastCGI for writing CGI-like programs in persistent processes, external to the web server. SCGI is less featureful than FastCGI, but has the advantage that it does not require an external library.<br />
<br />
Install [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/scgi-0.1 SCGI], import Network.SCGI, and use runSCGI. Everything else is then done inside a CGI monad as above.<br />
<br />
<br />
=== URL rewriting / dispatching ===<br />
<br />
Easy to use and expressive [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/UrlDisp URL dispatching library] is available on Hackage.<br />
<br />
<br />
=== Dynamic loading ===<br />
<br />
<br />
== Database-driven web-applications ==<br />
<br />
<br />
=== Database connectivity ===<br />
<br />
See [http://hackage.haskell.org/package/Takusen Takusen] and [http://software.complete.org/software/projects/show/hdbc HDBC]. If you would like to write queries in Haskell (and not SQL), see also [http://haskelldb.sourceforge.net/ HaskellDB], which integrates with HDBC.<br />
<br />
<br />
==== Persistent DB connections with FastCGI ====<br />
<br />
FastCGI aren't restarted for each request, only the runFastCGI part is re-run. Everything (handles, datastructures etc.) you do outside of that loop will be persistent. However you need to handle errors yourself, because you're operating outside of handleErrors.<br />
<br />
<br />
=== Web services ===<br />
<br />
=== Static web site generators ===<br />
<br />
* [http://hackage.haskell.org/package/hakyll Hakyll]<br />
* [http://hackage.haskell.org/package/yst Yst]<br />
* [http://hackage.haskell.org/package/halipeto Halipeto]<br />
<br />
== Web frameworks ==<br />
<br />
* [http://turbinado.org/Home Turbinado], an early stab at Ruby On Rails.<br />
* [http://docs.yesodweb.com/ Yesod Web Framework], for RESTful, type-safe web applications. Built on top of the WAI, so you can serve via standalone server, CGI, FastCGI or anything else with a WAI handler.<br />
<br />
== Existing applications ==<br />
<br />
* [http://hackage.haskell.org/ HackageDB web interface].<br />
<br />
* [http://tutorial.happstack.com/ Real World HAppS: The Cabalized, Self-Demoing HAppS Tutorial].<br />
<br />
* [http://github.com/jgm/gitit Gitit, a wiki written using Git, HAppS and Pandoc].<br />
<br />
* [http://www.bringert.net/ Hope].<br />
<br />
* [http://www.happstack.com Happstack]<br />
<br />
<br />
== See also ==<br />
<br />
* The blog article [http://wrwills.webfactional.com/2009/10/30/Haskell-on-a-Webfaction-Host Haskell on a Webfaction Host].<br />
<br />
<br />
''Authors: Björn Bringert''<br />
''Authors: Don Stewart''</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Web/Literature/Practical_web_programming_in_Haskell&diff=36529
Web/Literature/Practical web programming in Haskell
2010-08-18T09:01:21Z
<p>CaleGibbard: separate the type signature and comment about getInput with a small piece of text to make it obvious that it's not part of the same chunk of code.</p>
<hr />
<div>[[Category:Tutorials]]<br />
[[Category:Web]]<br />
{{Template:Formal under construction}}<br />
<br />
'''NOTE: I believe a lot of the information on this page is dated, and will lead beginners in the wrong direction. I've begun documenting some of the more modern options for Haskell web development on the [[Web]] page of this wiki. -- Michael Snoyman'''<br />
<br />
<br />
== Introduction ==<br />
<br />
This tutorial aims to get you started with writing web applications<br />
in Haskell. We describe a relatively light-weight <br />
approach to Haskell web programming<br />
which uses a CGI library and an XHTML combinator library. <br />
<br />
We think that while the approach we describe here is not as sophisticated<br />
or innovative as some other approaches, it is simple, portable and easy<br />
to understand if you are already familiar with web programming in other <br />
languages.<br />
<br />
The tutorial starts with preliminaries such as how to install the<br />
necessary software and how to compile and run your web<br />
applications. We then show a number of working small example programs<br />
which introduce the basic features of the CGI and XHtml libraries. We<br />
then move on to how to use monad transformers to add application<br />
specific functionality such as sessions to the CGI monad, and how to<br />
create database-driven web applications.<br />
We also present FastCGI, and an approach to using dynamically<br />
loaded Haskell code.<br />
<br />
<br />
=== Other approaches ===<br />
<br />
[Web Authoring System Haskell <br />
(WASH) [http://www.informatik.uni-freiburg.de/~thiemann/WASH/].<br />
Domain-specific embedded language. Type-safe forms handling. <br />
Threads continuation through client. This gives good<br />
back-button and session splitting properties.<br />
<br />
Haskell Application Server <br />
(HAppS) [http://happs.org/].<br />
Complete system including web server in one program.<br />
Uses XSLT for output.<br />
<br />
[http://www.happstack.com Happstack] is the successor to HAppS. It is a complete system including a web server and datatbase system in one program. It has many template options including HSP, HStringTemplate, Hamlet, XSLT, and more!<br />
<br />
Haskell Server Pages <br />
(HSP) [http://www.cs.chalmers.se/~d00nibro/hsp/].<br />
Uses preprocessor to make XML tags into Haskell expressions.<br />
Dynamic compilation.<br />
<br />
<br />
=== Assumed knowledge ===<br />
<br />
This tutorial is not meant as an introduction to Haskell or web programming.<br />
We will assume that you have some familiarity with the following <br />
concepts:<br />
<br />
<br />
==== Haskell ====<br />
<br />
This tutorial is not meant as a first introduction to Haskell. If you<br />
want to learn about Haskell in general, have a look at the lists of <br />
[[books and tutorials]]. You may want to start with [[Haskell in 5 steps]].<br />
<br />
<br />
==== (X)HTML ====<br />
<br />
[http://www.w3.org/MarkUp/ HTML (HyperText Markup Language)] is the <br />
"the lingua franca for publishing hypertext on the World Wide Web''.<br />
The XHtml library which we use in this tutorial produces <br />
[http://www.w3.org/TR/xhtml1/ XHTML 1.0], which is <br />
[http://www.w3.org/TR/html401/ HTML 4.0] formulated as <br />
[http://www.w3.org/XML/ XML].<br />
<br />
The combinators in the XHtml library do not make much sense unless you<br />
understand at least some parts of HTML. <br />
<br />
<br />
==== CGI ====<br />
<br />
CGI (Common Gateway Interface) programs are programs which run on the<br />
web server. They are given input which comes from the user's browser, <br />
and their output is given to the browser.<br />
<br />
To really understand how the CGI library works, you probably need to know<br />
a thing or two about CGI. ([http://www.comp.leeds.ac.uk/Perl/Cgi/start.html Tutorial].) <br />
The authoritative resource on CGI is the<br />
[http://hoohoo.ncsa.illinois.edu/cgi/interface.html CGI specification].<br />
<br />
<br />
== Required software ==<br />
<br />
=== Haskell compiler ===<br />
<br />
[[GHC]], the Glasgow Haskell <br />
Compiler, is the Haskell implementation that we will use in this tutorial. <br />
However, any Haskell implementation that supports Haskell98 and multi-parameter<br />
type classes should work.<br />
<br />
<br />
=== Libraries: xhtml and cgi ===<br />
<br />
If your Haskell implementation does not come with the <tt>xhtml</tt> and<br />
<tt>cgi</tt> packages, download them from <br />
[http://hackage.haskell.org/packages/hackage.html HackageDB].<br />
<br />
<br />
=== Web server ===<br />
<br />
You need to have access to a web server on which you can run CGI programs.<br />
The most convenient way to do this when learning and developing is to run<br />
a web server on your development machine. If you run the programs on some<br />
other machine you need to make sure that you compile your programs <br />
so that they can run on that machine. This normally means that the machines<br />
must to have the same architecture and run the same operating system. <br />
<br />
<br />
====Deploying statically linked applications ====<br />
<br />
Linking your applications statically by giving the flags <tt>-static<br />
-optl-static</tt> to GHC will avoid problems with missing libraries on<br />
the web server.<br />
<br />
For example, this simple program,<br />
<br />
<haskell><br />
import Database.SQLite<br />
main = print "hey, test this"<br />
</haskell><br />
<br />
when compiled as $ ghc A.hs --make is dynamically linked against:<br />
<br />
<haskell><br />
$ ldd A<br />
A:<br />
Start End Type Open Ref GrpRef Name<br />
0000000000000000 0000000000000000 exe 1 0 0 A<br />
0000000041a85000 0000000041ee5000 rlib 0 1 0 /usr/local/lib/libsqlite3.so.9.0<br />
0000000049b04000 0000000049f1d000 rlib 0 1 0 /usr/lib/libm.so.2.3<br />
0000000042213000 000000004264f000 rlib 0 1 0 /usr/local/lib/libgmp.so.7.0<br />
0000000047d0e000 00000000481e0000 rlib 0 1 0 /usr/lib/libc.so.42.0<br />
0000000047900000 0000000047900000 rtld 0 1 0 /usr/libexec/ld.so<br />
</haskell><br />
<br />
Now, we can just pass some linker flags through to statically link this lot,<br />
<br />
<haskell><br />
$ ghc A.hs --make -optl-static -no-recomp<br />
$ ldd A<br />
ldd: A: not a dynamic executable<br />
$ file A<br />
A: ELF 64-bit LSB executable, AMD64, version 1, for OpenBSD, statically linked, not stripped<br />
</haskell><br />
<br />
You could also use the [[Haskell Web Server]].<br />
<br />
'''Caveats:'''<br />
<br />
* The <tt>-static</tt> flag in GHC 6.8.2 does not link the libraries in the correct order, resulting in a link failure (which you can hack around if you have to by shuffling <tt>-lpthread</tt> after <tt>-lrt</tt> in the gargantuan linker invocation). This problem should disappear with GHC 6.8.3.<br />
* Sometimes you will need to add <tt>extra-libraries</tt> fields to various libraries' <tt>.cabal</tt> files. This manifests as missing symbols. Note that many linkers are sensitive to the order of the <tt>-l</tt> arguments, so the order of libraries in this field matters.<br />
<br />
<br />
== Compiling and running web applications ==<br />
<br />
Use GHC to produce a binary executable called <tt>prog.cgi</tt> from the Haskell <br />
source code file <tt>prog.hs</tt>:<br />
<pre><br />
ghc --make -package cgi -package xhtml -o prog.cgi prog.hs<br />
</pre><br />
<br />
Put the compiled program in the cgi-bin directory,<br />
or give it the extension .cgi, depending on the configuration<br />
of the web server.<br />
<br />
Linking your applications statically <br />
by giving the flags <tt>-static -optl-static</tt> to GHC <br />
will avoid problems with missing libraries on the web server.<br />
<br />
To run the compiled program, visit the URL of the CGI <br />
program with your web browser.<br />
<br />
<br />
== Simple examples ==<br />
<br />
=== Hello World ===<br />
<br />
Here is a very simple example which just outputs some static HTML.<br />
The type signatures in this code are optional. We show them here <br />
for clarity, but omit them in some later examples.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
page :: Html <br />
page = body << h1 << "Hello World!"<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = output $ renderHtml page<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
The <code>page</code> function constructs an HTML document which consists<br />
of a body containing a single header element which contains the text<br />
"Hello World". The CGI-action <code>cgiMain</code> renders the HTML document<br />
as a string, and produces that string as output. The <code>main</code> function<br />
runs <code>cgiMain</code>, using the normal CGI protocol for input and output.<br />
It also uses <code>handleErrors</code> to output an error page in case |cgiMain|<br />
throws an exception.<br />
<br />
Fans of one-liners may like this version better (<code>handleErrors</code> has been <br />
omitted since this simple program will not throw any exceptions):<br />
<br />
<haskell><br />
import Text.XHtml<br />
import Network.CGI<br />
<br />
main = runCGI $ output $ renderHtml $ body << h1 << "Hello World!"<br />
</haskell><br />
<br />
These are some of the important functions used in this example:<br />
<br />
<haskell><br />
-- creates a string containing the HTML document.<br />
renderHtml :: Html -> String<br />
<br />
-- outputs a string as the body of the HTTP response.<br />
output :: String -> CGI CGIResult<br />
<br />
-- Catches any exception thrown by the given CGI action, returns an <br />
-- error page with a 500 Internal Server Error, showing the exception <br />
-- information, and logs the error.<br />
handleErrors :: CGI CGIResult -> CGI CGIResult<br />
<br />
-- Runs a CGI action which produces a CGIResult, using the CGI protocol<br />
-- to get the inputs and send the outputs.<br />
runCGI :: CGI CGIResult -> IO ()<br />
</haskell><br />
<br />
<br />
==== HTML combinators ====<br />
<br />
See also [http://cpansearch.perl.org/src/AUTRIJUS/Language-Haskell-0.01/hugs98-Nov2003/fptools/hslibs/text/html/doc/doc.htm].<br />
<br />
<code>Html</code> is the type of HTML fragments. It comes from the <code>Text.XHtml</code> module.<br />
There are functions for all XHTML 1.0 elements. <br />
Some examples:<br />
<br />
* header, body<br />
* h1, h2, ...<br />
* thediv<br />
* p<br />
* image<br />
<br />
The <code><<</code> operator is used for nesting HTML.<br />
<br />
<code>+++</code> concatenates HTML.<br />
<br />
Attributes are added to tags using the <code>!</code> operator.<br />
<br />
The function <code>renderHtml</code> (FIXME: explain variants) produces a string containing the<br />
document.<br />
<br />
<br />
=== Getting user input ===<br />
<br />
This program shows a form which asks the user for her name.<br />
When the form is submitted, the program greets the user by name.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
inputForm = form << [paragraph << ("My name is " +++ textfield "name"),<br />
submit "" "Submit"]<br />
<br />
greet n = paragraph << ("Hello " ++ n ++ "!")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain = do mn <- getInput "name"<br />
let x = maybe inputForm greet mn<br />
output $ renderHtml $ page "Input example" x<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
This code makes use of the getInput function from the CGI library:<br />
<br />
<haskell><br />
-- Get the value of an input variable, for example from a form. <br />
-- If the variable has multiple values, the first one is returned.<br />
getInput :: String -> CGI (Maybe String)<br />
</haskell><br />
<br />
<br />
=== Cookies ===<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromMaybe)<br />
<br />
hello :: Int -> Html<br />
hello 0 = h1 << "Welcome!"<br />
+++ p << "This is the first time I see you."<br />
hello c = h1 << "Welcome back!"<br />
+++ p << ("I have seen you " ++ show c ++ " times before.")<br />
<br />
page :: String -> Html -> Html<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = do c <- liftM (fromMaybe 0) $ readCookie "mycookie"<br />
setCookie (newCookie "mycookie" (show (c+1)))<br />
output $ renderHtml $ page "Cookie example" $ hello c<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
Here we use <code>newCookie</code>, <code>setCookie</code> and <code>readCookie</code> to store and retrieve a counter<br />
cookie in the browser. If you want to get the string value of a cookie, use <code>getCookie</code> instead of <code>readCookie</code>.<br />
<br />
<br />
=== File uploads ===<br />
<br />
FIXME: use a safer example<br />
<br />
<haskell><br />
-- Accepts file uploads and saves the files in the given directory.<br />
-- WARNING: this script is a SECURITY RISK and only for <br />
-- demo purposes. Do not put it on a public web server.<br />
<br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import qualified Data.ByteString.Lazy as BS<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromJust)<br />
<br />
uploadDir = "../upload"<br />
<br />
fileForm = form ! [method "post", enctype "multipart/form-data"]<br />
<< [afile "file", submit "" "Upload"]<br />
saveFile n =<br />
do cont <- liftM fromJust $ getInputFPS "file"<br />
let f = uploadDir ++ "/" ++ basename n<br />
liftIO $ BS.writeFile f cont<br />
return $ paragraph << ("Saved as " +++ anchor ! [href f] << f +++ ".")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
basename = reverse . takeWhile (`notElem` "/\\") . reverse<br />
<br />
cgiMain = <br />
do mn <- getInputFilename "file"<br />
h <- maybe (return fileForm) saveFile mn<br />
output $ renderHtml $ page "Upload example" h<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
We first output a file upload form, which should use the HTTP POST method, <br />
and the multipart/form-data content type. Here we seen an example of the use of<br />
HTML attributes, added with the <code>!</code> operator.<br />
<br />
For efficiency reasons, we use Data.ByteString.Lazy to represent the file contents.<br />
getInputFPS gets the value of an input variable as a lazy ByteString.<br />
<br />
<br />
=== Error handling ===<br />
<br />
handleErrors catches all exceptions and <br />
outputs a default error page with some information about the exception.<br />
You can write you own exception handler if you want to do something else<br />
when an exception is thrown. It can be useful to set<br />
the response code, e.g. 404.<br />
<br />
<br />
=== Returning non-HTML ===<br />
<br />
Of course we do not have to output HTML. Use setHeader to set the value<br />
of the Content-type header, and you can output whatever string you like. <br />
<br />
In this example we return an image:<br />
<br />
<haskell><br />
import Network.CGI<br />
import System.IO<br />
import qualified Data.ByteString.Lazy as B<br />
<br />
main = do<br />
b <- B.readFile "./img/test.jpg" -- read the image<br />
runCGI $ handleErrors (cgiMain b)<br />
<br />
cgiMain :: B.ByteString -> CGI CGIResult<br />
cgiMain p = do<br />
-- we need to set the appropriate content-type<br />
setHeader "Content-type" "image/jpg"<br />
outputFPS p<br />
</haskell><br />
<br />
Examples: RSS<br />
<br />
<br />
=== Setting response headers ===<br />
<br />
You can use the <code>setHeader</code> function to set arbitrary HTTP response headers.<br />
You can also set the response code, as seen above.<br />
<br />
Example: output raw file data (with last-modified)<br />
<br />
<br />
== Going further ==<br />
<br />
This section explores some of possibilities beyond the basic web application<br />
programming.<br />
<br />
<br />
=== Extending the CGI monad with monad transformers ===<br />
<br />
At this point, you should be able to create many useful CGI scripts.<br />
As your scripts get more ambitious, however, you may find yourself<br />
needing to pass "global" parameters to your CGI actions (e.g. database<br />
connections, session information.) Rather than explicitly passing<br />
these values around, you can extend the CGI monad to do this work for<br />
you.<br />
<br />
The <hask>Network.CGI.Monad</hask> module defines a CGI monad<br />
transformer, allowing us to build a new monad that does everything the<br />
CGI monad does -- and more!<br />
<br />
For example, let's define a new CGI monad that provides a database<br />
connection (in this example, we use the<br />
<hask>Database.HSQL.PostgreSQL</hask> module for our database.) Since<br />
it will be used by the CGI application, I'll call the new monad "App".<br />
<br />
Should this not compile for you, you need to enable some extensions:<br />
<haskell><br />
{-# LANGUAGE GeneralizedNewtypeDeriving #-}<br />
{-# LANGUAGE FlexibleInstances #-}<br />
</haskell><br />
<br />
After importing the appropriate modules, we define a new type,<br />
<hask>AppT</hask> that is made up of two monad transformers,<br />
<hask>CGIT</hask> and <hask>ReaderT</hask>. The <hask>CGIT</hask><br />
monad "wraps" the base monad "m". The <hask>CGIT</hask> monad, in<br />
turn, is wrapped by the <hask>ReaderT</hask> monad, which contains, in<br />
its environment, the database <hask>Connection</hask>.<br />
<br />
<hask>AppT</hask> takes two type parameters. The first is the base<br />
monad that the monad transformers are modifying. Usually this will be<br />
the <hask>IO</hask> monad. The second type is the data type that an<br />
action in the monad will return.<br />
<br />
<haskell><br />
import Control.Monad.Reader<br />
import Network.CGI<br />
import Network.CGI.Monad<br />
import Database.HSQL.PostgreSQL<br />
<br />
newtype AppT m a = App (ReaderT Connection (CGIT m) a)<br />
deriving (Monad, MonadIO, MonadReader Connection)<br />
</haskell><br />
<br />
Like <hask>CGI</hask>, we make a type synonym that defines the most<br />
common use of this new monad.<br />
<br />
<haskell><br />
type App a = AppT IO a<br />
</haskell><br />
<br />
We're not quite finished defining <hask>App</hask> yet. In order to be<br />
used like the CGI monad, <hask>App</hask> needs to be an instance of<br />
the <hask>MonadCGI</hask> class. This class defines two functions that<br />
we must support.<br />
<br />
<haskell><br />
instance MonadCGI (AppT IO) where<br />
cgiAddHeader n v = App $ lift $ cgiAddHeader n v<br />
cgiGet x = App $ lift $ cgiGet x<br />
</haskell><br />
<br />
So now we have an App monad that gives us all the functionality of<br />
CGI, but also carries around a database connection. The last step is<br />
to define the function that creates the monad so we can run actions<br />
inside it.<br />
<br />
<haskell><br />
import Control.Exception (bracket)<br />
import System.IO (stdin, stdout)<br />
<br />
runApp :: App CGIResult -> IO ()<br />
runApp (App a) =<br />
bracket (connect "host" "db" "user" "password")<br />
disconnect<br />
(\c -> do { env <- getCGIVars<br />
; hRunCGI env stdin stdout (runCGIT (runReaderT a c))<br />
; return () } )<br />
</haskell><br />
<br />
(either fill in your account/password information, or change<br />
<hask>runApp</hask> to accept the parameters as function arguments.)<br />
The function uses <hask>bracket</hask> so that the database connection<br />
gets released properly when the monad ends or if an exception is<br />
thrown.<br />
<br />
<br />
=== Templating ===<br />
<br />
There are times when you absolutely do not want to embed (X)HTML in Haskell. You can separate the code and the presentation (the Holy Grail of erm, web development). The code will be, well, Haskell, and the presentation will be buried inside templates. This might not be the case: fortunately, there is a very nice templating engine available: [[HStringTemplate]]; also very useful is [http://hackage.haskell.org/package/hakyll hakyll], a simple static site generator library, mainly aimed at creating blogs and brochure sites.<br />
<br />
<br />
=== FastCGI ===<br />
<br />
[http://www.fastcgi.com/ FastCGI] is a standard for CGI-like programs that are not restarted<br />
for every request. This reduces the overhead involved in handling each <br />
request, and reduces the servers response time for each request.<br />
The overhead involved in starting a new process for each<br />
request can also include the need to set up new DB connections <br />
every time. With FastCGI, DB connections can be reused.<br />
<br />
Install FastCGI. Get a web server which can run FastCGI programs.<br />
Import Network.FastCGI. Use runFastCGI.<br />
<br />
See also a tutorial by Paul R Brown: [http://mult.ifario.us/p/wiring-haskell-into-a-fastcgi-web-server Wiring Haskell Into a FastCGI Web Server]<br />
<br />
Take a look at lightweight, minimalistic FastCGI-based web frameworks: [http://community.haskell.org/~sclv/hvac/ HVAC] (Haskell view and controller) and [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/kibro Kibro].<br />
<br />
<br />
=== SCGI ===<br />
<br />
[http://www.mems-exchange.org/software/scgi/ SCGI] is a simpler alternative to FastCGI for writing CGI-like programs in persistent processes, external to the web server. SCGI is less featureful than FastCGI, but has the advantage that it does not require an external library.<br />
<br />
Install [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/scgi-0.1 SCGI], import Network.SCGI, and use runSCGI. Everything else is then done inside a CGI monad as above.<br />
<br />
<br />
=== URL rewriting / dispatching ===<br />
<br />
Easy to use and expressive [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/UrlDisp URL dispatching library] is available on Hackage.<br />
<br />
<br />
=== Dynamic loading ===<br />
<br />
<br />
== Database-driven web-applications ==<br />
<br />
<br />
=== Database connectivity ===<br />
<br />
See [http://hackage.haskell.org/package/Takusen Takusen] and [http://software.complete.org/software/projects/show/hdbc HDBC]. If you would like to write queries in Haskell (and not SQL), see also [http://haskelldb.sourceforge.net/ HaskellDB], which integrates with HDBC.<br />
<br />
<br />
==== Persistent DB connections with FastCGI ====<br />
<br />
FastCGI aren't restarted for each request, only the runFastCGI part is re-run. Everything (handles, datastructures etc.) you do outside of that loop will be persistent. However you need to handle errors yourself, because you're operating outside of handleErrors.<br />
<br />
<br />
=== Web services ===<br />
<br />
=== Static web site generators ===<br />
<br />
* [http://hackage.haskell.org/package/hakyll Hakyll]<br />
* [http://hackage.haskell.org/package/yst Yst]<br />
* [http://hackage.haskell.org/package/halipeto Halipeto]<br />
<br />
== Web frameworks ==<br />
<br />
* [http://turbinado.org/Home Turbinado], an early stab at Ruby On Rails.<br />
* [http://docs.yesodweb.com/ Yesod Web Framework], for RESTful, type-safe web applications. Built on top of the WAI, so you can serve via standalone server, CGI, FastCGI or anything else with a WAI handler.<br />
<br />
== Existing applications ==<br />
<br />
* [http://hackage.haskell.org/ HackageDB web interface].<br />
<br />
* [http://tutorial.happstack.com/ Real World HAppS: The Cabalized, Self-Demoing HAppS Tutorial].<br />
<br />
* [http://github.com/jgm/gitit Gitit, a wiki written using Git, HAppS and Pandoc].<br />
<br />
* [http://www.bringert.net/ Hope].<br />
<br />
* [http://www.happstack.com Happstack]<br />
<br />
<br />
== See also ==<br />
<br />
* The blog article [http://wrwills.webfactional.com/2009/10/30/Haskell-on-a-Webfaction-Host Haskell on a Webfaction Host].<br />
<br />
<br />
''Authors: Björn Bringert''<br />
''Authors: Don Stewart''</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Tutorials/Programming_Haskell/Introduction&diff=35078
Tutorials/Programming Haskell/Introduction
2010-07-01T01:34:30Z
<p>CaleGibbard: </p>
<hr />
<div>It's about time we got some job done in [[Haskell]], eh? Now, one of my<br />
favourite programming books as an undergraduate was the Camel Book,<br />
"Programming Perl". It was full of lots of practical examples of Perl<br />
code, written well. (And I'm grateful to Larry Wall, Tom Christiansen<br />
and Randal Schwartz for writing the book that made programming fun).<br />
<br />
So what would it look like if we wrote a Haskell tutorial in this style?<br />
Let's have at it!<br />
<br />
== Getting started ==<br />
<br />
Like some languages Haskell can be both compiled and interpreted. The<br />
most widely used implementation of Haskell currently is GHC, which<br />
provides both an optimising native code compiler, and an interactive<br />
bytecode interpreter. I'll be using [http://haskell.org/ghc GHC] <br />
(or its interactive front end, GHCi, for all code. So grab a copy of GHC<br />
now, from your package system, or the [http://haskell.org/ghc GHC home page].<br />
<br />
Start up GHCi:<br />
<br />
$ ghci<br />
___ ___ _<br />
/ _ \ /\ /\/ __(_)<br />
/ /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98.<br />
/ /_\\/ __ / /___| | http://www.haskell.org/ghc/<br />
\____/\/ /_/\____/|_| Type :? for help.<br />
<br />
Loading package base ... linking ... done.<br />
Prelude><br />
<br />
The interpreter now waits for your code fragments. The "Prelude" prompt<br />
indicates which library modules are in scope, and in this case, only the basic<br />
language module, known as <br />
[http://www.cse.unsw.edu.au/~dons/data/Prelude.html the Prelude].<br />
<br />
Now we can start running Haskell code.<br />
<br />
<haskell><br />
Prelude> "G'day, world!"<br />
"G'day, world!"<br />
<br />
Prelude> putStrLn "G'day, world!"<br />
G'day, world!<br />
</haskell><br />
<br />
You can compile this code to a native binary using GHC, by writing in a source file:<br />
<br />
<haskell><br />
main = putStrLn "G'day, world!"<br />
</haskell><br />
<br />
and then compiling the source to native code. Assuming your file is A.hs:<br />
<br />
$ ghc A.hs<br />
<br />
This produces a new executable, ./a.out (a.out.exe on windows), which you can<br />
run like any other program on your system:<br />
<br />
$ ./a.out<br />
G'day, world!<br />
<br />
==Variables==<br />
<br />
We can name arbitrary fragments of Haskell using variables. Like so:<br />
<br />
<haskell><br />
phrase = "G'day, world!"<br />
main = putStrLn phrase<br />
</haskell><br />
<br />
We don't have to define what type phrase is, as Haskell uses type inference to<br />
infer at compile time the types of all expressions in the program. As "G'day,<br />
world!" is a string, so must phrase be a string. There are a bunch of basic<br />
types of values to play with. Here's a small sample:<br />
<br />
<haskell><br />
answer = 42<br />
pi = 3.141592653589793238462643383279502884197169399375105820974944592<br />
avocados = 6.02e23<br />
pet = "Lambda"<br />
sign = "I love my " ++ pet<br />
coat = "It costs $100"<br />
hence = "whence"<br />
thence = hence<br />
moles = 2.5<br />
x = moles * avocados<br />
c = '#'<br />
pair = (2.5, "lambdas")<br />
list = [5,6,4,3,1]<br />
options = Just "done"<br />
failed = Nothing<br />
void = ()<br />
</haskell><br />
<br />
One important thing to remember is that Haskell's variables, like in most<br />
functional programming languages, are like variables in mathematics, and are<br />
just names for expressions. They're explicitly not [http://www.haskell.org/pipermail/haskell-cafe/2006-December/020147.html mutable boxes], <br />
like in most imperative programming languages. As a result, you never need to<br />
worry about initialising a Haskell variable, nor do you need to worry about the<br />
current value <i>in</i> a variable: it always has the same value, and can<br />
always be replaced with its definition. So the following behaves<br />
just like it would in maths:<br />
<br />
<haskell><br />
answer = 42<br />
another = answer + 1<br />
more = another + answer<br />
main = print more<br />
</haskell><br />
<br />
That is,<br />
<br />
$ ghc A.hs<br />
$ ./a.out<br />
85<br />
<br />
Now, since variables are just names for program fragments, you can evaluate<br />
Haskell on paper by replacing all names with their definition, until you reach<br />
a final value, like so:<br />
<br />
<haskell><br />
main = print more<br />
=><br />
main = print (another + answer)<br />
=><br />
main = print ((answer + 1) + answer)<br />
=><br />
main = print ((answer + 1) + 42)<br />
=><br />
main = print ((42 + 1) + 42)<br />
=><br />
main = print (43 + 42)<br />
=><br />
main = print 85<br />
=><br />
85<br />
</haskell><br />
<br />
Having such a simple system for variables allows for a wide range of<br />
interesting optimisations, and makes understanding what a program is doing at<br />
any point much easier, since you don't have to worry about what state a<br />
variable might currently be in. (Of course, some problems need (threadsafe) <br />
[http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html mutable boxes], and they're available as a library for when you need that).<br />
<br />
==Collections==<br />
<br />
Often you need to collect a bunch of values together into some kind of<br />
collection. Haskell has many many collection types, but in particular, it has<br />
lists and finite maps, which operate much like arrays and hashes of the<br />
imperative world.<br />
<br />
===Lists===<br />
<br />
A list is just an ordered, um, list of values. They can be nested, and<br />
transformed in all sorts of ways, using functions. Assuming your file, A.hs,<br />
contains:<br />
<br />
<haskell><br />
home = ["couch", "chair", "table", "stove"]<br />
</haskell><br />
<br />
We can play around with this stuff like so:<br />
<br />
<haskell><br />
$ ghci A.hs<br />
<br />
*Main> home<br />
["couch","chair","table","stove"]<br />
<br />
*Main> head home<br />
"couch"<br />
<br />
*Main> tail home<br />
["chair","table","stove"]<br />
<br />
*Main> last home<br />
"stove"<br />
<br />
*Main> home !! 2<br />
"table"<br />
<br />
*Main> reverse home<br />
["stove","table","chair","couch"]<br />
<br />
*Main> map reverse home<br />
["hcuoc","riahc","elbat","evots"]<br />
</haskell><br />
<br />
Loading in the [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html List library] <br />
gives us some more functions to use:<br />
<br />
<haskell><br />
*Main> :m + Data.List<br />
<br />
*Main Data.List> intersperse "#" home<br />
["couch","#","chair","#","table","#","stove"]<br />
<br />
*Main Data.List> concat (intersperse "#" home)<br />
"couch#chair#table#stove"<br />
<br />
*Main Data.List> home \\ ["table","stove"]<br />
["couch","chair"]<br />
</haskell><br />
<br />
===Finite Maps===<br />
<br />
[http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Map.html Finite maps]<br />
(or maps) are the lookup tables of purely functional programming. Whenever<br />
you'd use some kind of hash in an imperative language, you can replace it with<br />
a Map in Haskell.<br />
<br />
Like hashes, maps can be seen as a table of pairs of keys and values. You can<br />
declare a new map:<br />
<br />
<haskell><br />
import Data.Map<br />
<br />
days = fromList<br />
[ ("Sun", "Sunday" )<br />
, ("Mon", "Monday" )<br />
, ("Tue", "Tuesday" )<br />
, ("Wed", "Wednesday" )<br />
, ("Thu", "Thursday" )<br />
, ("Fri", "Friday" )<br />
, ("Sat", "Saturday" ) ]<br />
</haskell><br />
<br />
You can also convert a map to a list, using (well, duh!) toList:<br />
<br />
<haskell><br />
*Main> toList days<br />
[("Fri","Friday"),("Mon","Monday"),("Sat","Saturday")<br />
,("Sun","Sunday"),("Thu","Thursday"),("Tue","Tuesday")<br />
,("Wed","Wednesday")]<br />
</haskell><br />
<br />
Note that they come out unordered, just like in hashes. If you just want the keys of the map:<br />
<br />
<haskell><br />
*Main> keys days<br />
["Fri","Mon","Sat","Sun","Thu","Tue","Wed"]<br />
<br />
*Main> elems days<br />
["Friday","Monday","Saturday","Sunday","Thursday","Tuesday","Wednesday"]<br />
</haskell><br />
<br />
Since maps are a good structure for looking up values, you can search them using<br />
the lookup function. This function returns the element, if found: <br />
<br />
<haskell><br />
*Main> Data.Map.lookup "Tue" days<br />
"Tuesday"<br />
</haskell><br />
<br />
Since the name 'lookup' is also used by a list function of similar purpose in<br />
the Prelude, we use the <i>qualified</i> name here to disambiguate which<br />
'lookup' to use.<br />
<br />
===On failure===<br />
<br />
But what happens if the key is not found? (Feel free to skip this section if<br />
you don't care about errors yet) lookup will then fail, and how it fails<br />
depends on what kind of failure you want. Haskell goes to great lengths to make<br />
programming for failure flexible. For example, to fail with an exception:<br />
<br />
<haskell><br />
*Main> Data.Map.lookup "Thor" days<br />
*** Exception: user error (Data.Map.lookup: Key not found)<br />
</haskell><br />
<br />
Which is the same as failing with an IO error. We can specify this specifically<br />
with a type annotation, to say "fail with an IO error":<br />
<br />
<haskell><br />
*Main> Data.Map.lookup "Thor" days :: IO String<br />
*** Exception: user error (Data.Map.lookup: Key not found)<br />
</haskell><br />
<br />
Often you might instead prefer that some special value is returned on failure:<br />
<br />
<haskell><br />
*Main> Data.Map.lookup "Thors" days :: Maybe String<br />
Nothing<br />
</haskell><br />
<br />
Maybe you'd just like an empty list:<br />
<br />
<haskell><br />
*Main> Data.Map.lookup "Thor" days :: [String]<br />
[]<br />
</haskell><br />
<br />
Finally, you can always provide an explicit default value:<br />
<br />
<haskell><br />
*Main> findWithDefault "Not found" "Thor" days<br />
"Not found"<br />
</haskell><br />
<br />
Failure is entirely under your control! <br />
<br />
==Actions==<br />
<br />
Now, real programs interact with the outside world. They call functions which<br />
do IO, as a side effect, and then return some value. In Haskell, functions with<br />
side effects are often called <i>actions</i>, to distinguish them from normal<br />
Haskell functions (which behave like mathematical functions: they take inputs<br />
and return a result, with no side effects). Programming with side effects is<br />
carefully handled in Haskell, again to control the possibility of errors, and<br />
all functions which have side effects have a special type: the IO type. <br />
<br />
For example, the function to print a string has the following type (and you can<br />
ask the interpreter for the type interactively):<br />
<br />
<haskell><br />
Prelude> :t putStr<br />
putStr :: String -> IO ()<br />
</haskell><br />
<br />
which tells you that this function takes a String as an argument, does some IO<br />
side effect, and returns the null value. It is equivalent to the following C<br />
type:<br />
<br />
void putStr(char *);<br />
<br />
but with a bit of extra information, namely, that the function does some IO.<br />
We would print out some element of our map like so:<br />
<br />
<haskell><br />
main = print ("Tue in long form is " ++ findWithDefault "Not found" "Tue" days)<br />
<br />
*Main> main<br />
"Tue in long form is Tuesday"<br />
</haskell><br />
<br />
==An example==<br />
<br />
One of the classic programming puzzles for introducing real world problems is<br />
the 'class grade' problem. You have a text file containing a list of student<br />
names and their grades, and you'd like to extract various information and<br />
display it. In deference to The Camel Book, we'll follow this lead, and start<br />
with a file "grades", containing something like this:<br />
<br />
Alonzo 70<br />
Simon 94<br />
Henk 79<br />
Eugenio 69<br />
Bob 80<br />
Oleg 77<br />
Philip 73<br />
...<br />
<br />
Student's appear multiple times, with entries for each of their subjects Let's<br />
read this file, populate a map with the data, and print some statistical<br />
information about the results. First thing to do is import some basic libraries:<br />
<br />
<haskell><br />
import Data.Char<br />
import Data.Maybe<br />
import Data.List<br />
import Data.Map hiding (map)<br />
import Text.Printf<br />
</haskell><br />
<br />
And now here's the entire program, to read the grades file, compute all the<br />
averages, and print them:<br />
<br />
<haskell><br />
main = do<br />
src <- readFile "grades"<br />
let pairs = map (split.words) (lines src)<br />
let grades = foldr insert empty pairs<br />
mapM_ (draw grades) (sort (keys grades))<br />
where<br />
insert (s, g) = insertWith (++) s [g]<br />
split [name,mark] = (name, read mark)<br />
<br />
draw g s = printf "%s\t%s\tAverage: %f\n" s (show marks) avg<br />
where<br />
marks = findWithDefault (error "No such student") s g<br />
avg = sum marks / fromIntegral (length marks) :: Double<br />
</haskell><br />
<br />
==Running it==<br />
<br />
How do we run this program? There's lots of ways:<br />
<br />
===Compile it to native code===<br />
<br />
$ ghc -O Grades.hs<br />
<br />
$ ./a.out<br />
Alonzo [70.0,71.0] Average: 70.5<br />
Bob [80.0,88.0] Average: 84.0<br />
Eugenio [69.0,98.0] Average: 83.5<br />
Henk [79.0,81.0] Average: 80.0<br />
Oleg [77.0,68.0] Average: 72.5<br />
Philip [73.0,71.0] Average: 72.0<br />
Simon [94.0,83.0] Average: 88.5<br />
<br />
===Run it in the bytecode interpreter===<br />
<br />
$ runhaskell Grades.hs<br />
Alonzo [70.0,71.0] Average: 70.5<br />
Bob [80.0,88.0] Average: 84.0<br />
Eugenio [69.0,98.0] Average: 83.5<br />
Henk [79.0,81.0] Average: 80.0<br />
Oleg [77.0,68.0] Average: 72.5<br />
Philip [73.0,71.0] Average: 72.0<br />
Simon [94.0,83.0] Average: 88.5<br />
<br />
===Execute it interactively===<br />
<br />
$ ghci Grades.hs<br />
Prelude Main> main<br />
Alonzo [70.0,71.0] Average: 70.5<br />
Bob [80.0,88.0] Average: 84.0<br />
Eugenio [69.0,98.0] Average: 83.5<br />
Henk [79.0,81.0] Average: 80.0<br />
Oleg [77.0,68.0] Average: 72.5<br />
Philip [73.0,71.0] Average: 72.0<br />
Simon [94.0,83.0] Average: 88.5<br />
<br />
===Make the script executable===<br />
<br />
Under unix, you can use the #! convention to make a script executable. Add the<br />
following to the top of the source file:<br />
<br />
#!/usr/bin/env runhaskell<br />
<br />
And then set the script executable:<br />
<br />
$ chmod +x Grades.hs<br />
<br />
$ ./Grades.hs<br />
Alonzo [70.0,71.0] Average: 70.5<br />
Bob [80.0,88.0] Average: 84.0<br />
Eugenio [69.0,98.0] Average: 83.5<br />
Henk [79.0,81.0] Average: 80.0<br />
Oleg [77.0,68.0] Average: 72.5<br />
Philip [73.0,71.0] Average: 72.0<br />
Simon [94.0,83.0] Average: 88.5<br />
<br />
===Next week=== <br />
<br />
More IO!<br />
<br />
[[Category:Tutorials]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=The_Fibonacci_sequence&diff=32927
The Fibonacci sequence
2010-01-11T13:36:17Z
<p>CaleGibbard: </p>
<hr />
<div>Implementing the [http://en.wikipedia.org/wiki/Fibonacci_number Fibonacci sequence] is considered the "Hello, world!" of Haskell programming. This page collects Haskell implementations of the sequence.<br />
<br />
== Naive definition ==<br />
<br />
The standard definition can be expressed directly:<br />
<haskell><br />
fib 0 = 0<br />
fib 1 = 1<br />
fib n = fib (n-1) + fib (n-2)<br />
</haskell><br />
This implementation requires ''O(fib n)'' additions.<br />
<br />
== Linear operation implementations ==<br />
<br />
=== A fairly fast version, using some identities ===<br />
<br />
<haskell><br />
fib 0 = 0<br />
fib 1 = 1<br />
fib n | even n = f1 * (f1 + 2 * f2)<br />
| n `mod` 4 == 1 = (2 * f1 + f2) * (2 * f1 - f2) + 2<br />
| otherwise = (2 * f1 + f2) * (2 * f1 - f2) - 2<br />
where k = n `div` 2<br />
f1 = fib k<br />
f2 = fib (k-1)<br />
</haskell><br />
<br />
=== Using the infinite list of Fibonacci numbers ===<br />
<br />
One can compute the first ''n'' Fibonacci numbers with ''O(n)'' additions.<br />
If <hask>fibs</hask> is the infinite list of Fibonacci numbers, one can define<br />
<haskell><br />
fib n = fibs!!n<br />
</haskell><br />
<br />
==== Canonical zipWith implementation ====<br />
<br />
<haskell><br />
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)<br />
</haskell><br />
<br />
==== With scanl ====<br />
<br />
<haskell><br />
fibs = scanl (+) 0 (1:fibs)<br />
fibs = 0 : scanl (+) 1 fibs<br />
</haskell><br />
The recursion can be replaced with <hask>fix</hask>:<br />
<haskell><br />
fibs = fix (scanl (+) 0 . (1:))<br />
fibs = fix ((0:) . scanl (+) 1)<br />
</haskell><br />
<br />
==== With unfoldr ====<br />
<br />
<haskell><br />
fibs = unfoldr (\(a,b) -> Just (a,(b,a+b))) (0,1)<br />
</haskell><br />
<br />
==== With iterate ====<br />
<br />
<haskell><br />
fibs = map fst $ iterate (\(a,b) -> (b,a+b)) (0,1)<br />
</haskell><br />
<br />
==== With state ====<br />
<haskell><br />
import Control.Monad.State<br />
{-<br />
-- haskell translational of python algo<br />
def fib(n):<br />
a, b = 0, 1<br />
for _ in xrange(n):<br />
a, b = b, a + b<br />
return a<br />
print fib(1000)<br />
-}<br />
fib :: Integer -> Integer<br />
fib n = flip evalState (0,1) $ do<br />
forM (xrange n) $ \_ -> do<br />
(a,b) <- get<br />
put (b,a+b)<br />
(a,b) <- get<br />
return a <br />
<br />
xrange n = [0..(n-1)]<br />
</haskell><br />
<br />
== Logarithmic operation implementations ==<br />
<br />
=== Using 2x2 matrices ===<br />
<br />
The argument of <hask>iterate</hask> above is a [http://en.wikipedia.org/wiki/Linear_map linear transformation],<br />
so we can represent it as matrix and compute the ''n''th power of this matrix with ''O(log n)'' multiplications and additions.<br />
For example, using the [[Prelude_extensions#Matrices|simple matrix implementation]] in [[Prelude extensions]],<br />
<haskell><br />
fib n = head (apply (Matrix [[0,1], [1,1]] ^ n) [0,1])<br />
</haskell><br />
This technique works for any linear recurrence.<br />
<br />
=== Another fast fib ===<br />
<br />
(Assumes that the sequence starts with 1.)<br />
<haskell><br />
fib = fst . fib2<br />
<br />
-- | Return (fib n, fib (n + 1))<br />
fib2 0 = (1, 1)<br />
fib2 1 = (1, 2)<br />
fib2 n<br />
| even n = (a*a + b*b, c*c - a*a)<br />
| otherwise = (c*c - a*a, b*b + c*c)<br />
where (a,b) = fib2 (n `div` 2 - 1)<br />
c = a + b<br />
</haskell><br />
<br />
=== Fastest Fib in the West ===<br />
<br />
This was contributed by [http://www.haskell.org/pipermail/haskell-cafe/2005-January/008839.html wli]<br />
(It assumes that the sequence starts with 1.)<br />
<br />
<haskell><br />
import Data.List<br />
<br />
fib1 n = snd . foldl fib' (1, 0) . map (toEnum . fromIntegral) $ unfoldl divs n<br />
where<br />
unfoldl f x = case f x of<br />
Nothing -> []<br />
Just (u, v) -> unfoldl f v ++ [u]<br />
<br />
divs 0 = Nothing<br />
divs k = Just (uncurry (flip (,)) (k `divMod` 2))<br />
<br />
fib' (f, g) p<br />
| p = (f*(f+2*g), f^2 + g^2)<br />
| otherwise = (f^2+g^2, g*(2*f-g))<br />
</haskell><br />
<br />
An even faster version, given later by wli on the [[IRC channel]].<br />
<haskell><br />
import Data.List<br />
import Data.Bits<br />
<br />
fib :: Int -> Integer<br />
fib n = snd . foldl' fib' (1, 0) . dropWhile not $<br />
[testBit n k | k <- let s = bitSize n in [s-1,s-2..0]]<br />
where<br />
fib' (f, g) p<br />
| p = (f*(f+2*g), ss)<br />
| otherwise = (ss, g*(2*f-g))<br />
where ss = f*f+g*g<br />
</haskell><br />
<br />
== Constant-time implementations ==<br />
<br />
The Fibonacci numbers can be computed in constant time using Binet's formula.<br />
However, that only works well within the range of floating-point numbers<br />
available on your platform. Implementing Binet's formula in such a way that it computes exact results for all integers generally doesn't result in a terribly efficient implementation when compared to the programs above which use a logarithmic number of operations (and work in linear time).<br />
<br />
Beyond that, you can use [http://haskell.org/haskellwiki/Applications_and_libraries/Mathematics#Real_and_rational_numbers unlimited-precision floating-point numbers],<br />
but the result will probably not be any better than the [[#Log-time_implementations|log-time implementations]] above.<br />
<br />
=== Using Binet's formula ===<br />
<br />
<haskell><br />
fib n = round $ phi ** fromIntegral n / sq5<br />
where<br />
sq5 = sqrt 5 :: Double<br />
phi = (1 + sq5) / 2<br />
</haskell><br />
<br />
== Generalization of Fibonacci numbers ==<br />
The numbers of the traditional Fibonacci sequence are formed by summing its two preceding numbers, with starting values 0 and 1. Variations of the sequence can be obtained by using different starting values and summing a different number of predecessors.<br />
<br />
=== Fibonacci ''n''-Step Numbers ===<br />
The sequence of Fibonacci ''n''-step numbers are formed by summing ''n'' predecessors, using (''n''-1) zeros and a single 1 as starting values:<br />
<math><br />
F^{(n)}_k :=<br />
\begin{cases}<br />
0 & \mbox{if } 0 \leq k < n-1 \\<br />
1 & \mbox{if } k = n-1 \\<br />
\sum\limits_{i=k-n}^{(k-1)} F^{(n)}_i & \mbox{otherwise} \\<br />
\end{cases}<br />
</math><br />
<br />
Note that the summation in the current definition has a time complexity of ''O(n)'', assuming we memoize previously computed numbers of the sequence. We can do better than. Observe that in the following Tribonacci sequence, we compute the number 81 by summing up 13, 24 and 44:<br />
<br />
<math><br />
F^{(3)} = 0,0,1,1,2,4,7,\underbrace{13,24,44},81,149, \ldots <br />
</math><br />
<br />
The number 149 is computed in a similar way, but can also be computed as follows:<br />
<br />
<math><br />
149 = 24 + 44 + 81 = (13 + 24 + 44) + 81 - 13 = 81 + 81 - 13 = 2\cdot 81 - 13<br />
</math><br />
<br />
And hence, an equivalent definition of the Fibonacci ''n''-step numbers sequence is:<br />
<br />
<math><br />
F^{(n)}_k :=<br />
\begin{cases}<br />
0 & \mbox{if } 0 \leq k < n-1 \\<br />
1 & \mbox{if } k = n-1 \\<br />
1 & \mbox{if } k = n \\<br />
F^{(n)}_k := 2F^{(n)}_{k-1}-F^{(n)}_{k-(n+1)} & \mbox{otherwise} \\<br />
\end{cases}<br />
</math><br />
<br />
''(Notice the extra case that is needed)''<br />
<br />
Transforming this directly into Haskell gives us:<br />
<haskell><br />
nfibs n = replicate (n-1) 0 ++ 1 : 1 :<br />
zipWith (\b a -> 2*b-a) (drop n (nfibs n)) (nfibs n)<br />
</haskell><br />
This version, however, is slow since the computation of <hask>nfibs n</hask> is not shared. Naming the result using a let-binding and making the lambda pointfree results in:<br />
<haskell><br />
nfibs n = let r = replicate (n-1) 0 ++ 1 : 1 : zipWith ((-).(2*)) (drop n r) r<br />
in r<br />
</haskell><br />
<br />
<br />
== See also == <br />
<br />
* [http://cgi.cse.unsw.edu.au/~dons/blog/2007/11/29 Naive parallel, multicore version]<br />
* [[Fibonacci primes in parallel]]<br />
* [http://comments.gmane.org/gmane.comp.lang.haskell.cafe/19623 Discussion at haskell cafe]<br />
* [http://www.cubbi.org/serious/fibonacci/haskell.html Some other nice solutions]<br />
* In [http://projecteuler.net/ Project Euler], some of the problems involve Fibonacci numbers. There are some solutions in Haskell ('''Spoiler Warning:''' Do not look at solutions to Project Euler problems until you have solved the problems on your own.):<br />
** [[Euler_problems/1_to_10#Problem_2|Problem 2]]<br />
** [[Euler_problems/21_to_30#Problem_25|Problem 25]]<br />
** [[Euler_problems/101_to_110#Problem_104|Problem 104]]<br />
** [[Euler_problems/131_to_140#Problem_137|Problem 137]]<br />
<br />
[[Category:Code]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Pointfree&diff=31594
Pointfree
2009-11-15T22:03:19Z
<p>CaleGibbard: add Cont-derived implementation of swing</p>
<hr />
<div>__TOC__<br />
<br />
'''Pointfree Style'''<br />
<br />
It is very common for functional programmers to write functions as a<br />
composition of other functions, never mentioning the actual arguments<br />
they will be applied to. For example, compare:<br />
<br />
<haskell><br />
sum = foldr (+) 0<br />
</haskell><br />
<br />
with:<br />
<br />
<haskell><br />
sum' xs = foldr (+) 0 xs<br />
</haskell><br />
<br />
These functions perform the same operation, however, the former is more<br />
compact, and is considered cleaner. This is closely related to function<br />
pipelines (and to [http://www.vex.net/~trebla/weblog/pointfree.html unix shell scripting]<br />
): it is clearer to write <hask>let fn = f . g . h</hask> than to<br />
write <hask>let fn x = f (g (h x))</hask>.<br />
<br />
This style is particularly useful when deriving efficient programs by<br />
calculation and, in general, constitutes good discipline. It helps the writer<br />
(and reader) think about composing functions (high level), rather than<br />
shuffling data (low level).<br />
<br />
It is a common experience when rewriting expressions in pointfree style<br />
to derive more compact, clearer versions of the code -- explicit points<br />
often obscure the underlying algorithm.<br />
<br />
Point-free map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr (f . g) e<br />
</haskell><br />
<br />
versus pointful map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr f' e<br />
where f' a b = f (g a) b<br />
</haskell><br />
<br />
Some more examples:<br />
<br />
<haskell><br />
-- point-wise, and point-free member<br />
mem, mem' :: Eq a => a -> [a] -> Bool<br />
<br />
mem x lst = any (== x) lst<br />
mem' = any . (==)<br />
</haskell><br />
<br />
== But pointfree has more points! ==<br />
<br />
A common misconception is that the 'points' of pointfree style are the<br />
<hask>(.)</hask> operator (function composition, as an ASCII symbol),<br />
which uses the same identifier as the decimal point. This is wrong. The<br />
term originated in topology, a branch of mathematics which works with<br />
spaces composed of points, and functions between those spaces. So a<br />
'points-free' definition of a function is one which does not explicitly<br />
mention the points (values) of the space on which the function acts. In<br />
Haskell, our 'space' is some type, and 'points' are values. In the<br />
declaration:<br />
<haskell><br />
f x = x + 1<br />
</haskell><br />
we define the function <hask>f</hask> in terms of its action on an<br />
arbitrary point <hask>x</hask>. Contrast this with the points-free<br />
version:<br />
<haskell><br />
f = (+ 1)<br />
</haskell><br />
where there is no mention of the value on which the function is acting.<br />
<br />
== Background ==<br />
<br />
To find out more about this style, search for Squiggol and the<br />
Bird-Meertens Formalism, a style of functional programming by<br />
calculation that was developed by [http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications.html Richard Bird], [http://www.kestrel.edu/home/people/meertens/ Lambert Meertens], and<br />
others at Oxford University. [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/ Jeremy Gibbons] has also written a number of<br />
papers about the topic, which are cited below.<br />
<br />
== Tool support ==<br />
<br />
Thomas Yaeger has<br />
[http://www.cse.unsw.edu.au/~dons/code/lambdabot/Plugins/Pl/ written] a <br />
[http://haskell.org/haskellwiki/Lambdabot Lambdabot] <br />
plugin to automatically convert a large subset of Haskell expressions to<br />
pointfree form. This tool has made it easier to use the more abstract<br />
pointfree encodings (as it saves some mental gymnastics on the part of<br />
the programmer). You can experiment with this in the [[IRC channel|Haskell IRC channel]]. A stand-alone command-line version is available at [http://hackage.haskell.org/package/pointfree HackageDB] (package pointfree).<br />
<br />
The @pl (point-less) plugin is rather infamous for using the <hask>(->) a</hask> <br />
[[Monad|monad]] to obtain concise code. It also makes use of [[Arrow|Arrows]]. <br />
It also sometimes produces (amusing) code blow ups with the<br />
<hask>(.)</hask> operator. <br />
<br />
Recently, @unpl has been written, which<br />
(attempts) to unscramble @pl-ified code. It also has a [http://hackage.haskell.org/package/pointful stand-alone command-line version] (package pointful).<br />
<br />
A transcript:<br />
<br />
<haskell><br />
> pl \x y -> x y<br />
id<br />
<br />
> unpl id<br />
(\ a -> a)<br />
<br />
> pl \x y -> x + 1<br />
const . (1 +)<br />
<br />
> unpl const . (1 +)<br />
(\ e _ -> 1 + e)<br />
<br />
> pl \v1 v2 -> sum (zipWith (*) v1 v2)<br />
(sum .) . zipWith (*)<br />
<br />
> unpl (sum .) . zipWith (*)<br />
(\ d g -> sum (zipWith (*) d g))<br />
<br />
> pl \x y z -> f (g x y z)<br />
((f .) .) . g<br />
<br />
> unpl ((f .) .) . g<br />
(\ e j m -> f (g e j m))<br />
<br />
> pl \x y z -> f (g x y) z<br />
(f .) . g<br />
<br />
> unpl (f .) . g<br />
(\ d i -> f (g d i))<br />
<br />
> pl \x y z -> f z (g x y)<br />
(flip f .) . g<br />
<br />
> unpl (flip f .) . g<br />
(\ i l c -> f c (g i l))<br />
<br />
> pl \(a,b) -> (b,a)<br />
uncurry (flip (,))<br />
<br />
> pl f a b = b a<br />
f = flip id<br />
<br />
> pl \ x -> x * x<br />
join (*)<br />
<br />
> pl \a b -> a:b:[]<br />
(. return) . (:)<br />
<br />
> pl \x -> x+x+x<br />
(+) =<< join (+)<br />
<br />
> pl \a b -> Nothing<br />
const (const Nothing)<br />
<br />
> pl \(a,b) -> (f a, g b)<br />
f *** g<br />
<br />
> pl \f g h x -> f x `h` g x<br />
flip . (ap .) . flip (.)<br />
<br />
> pl \x y -> x . f . y<br />
(. (f .)) . (.)<br />
<br />
> pl \f xs -> xs >>= return . f<br />
fmap<br />
<br />
> pl \h f g x -> f x `h` g x<br />
liftM2<br />
<br />
> pl \f a b c d -> f b c d a<br />
flip . ((flip . (flip .)) .)<br />
<br />
> pl \a (b,c) -> a c b<br />
(`ap` snd) . (. fst) . flip<br />
<br />
> pl \x y -> compare (f x) (f y)<br />
((. f) . compare .)<br />
</haskell><br />
<br />
For many many more examples, google for the results of '@pl' in the<br />
[[IRC_channel|#haskell]] logs. (Or join #haskell on FreeNode and try it<br />
yourself!) It can, of course, get out of hand:<br />
<br />
<haskell><br />
> pl \(a,b) -> a:b:[]<br />
uncurry ((. return) . (:))<br />
<br />
> pl \a b c -> a*b+2+c<br />
((+) .) . flip flip 2 . ((+) .) . (*)<br />
<br />
> pl \f (a,b) -> (f a, f b)<br />
(`ap` snd) . (. fst) . (flip =<< (((.) . (,)) .))<br />
<br />
> pl \f g (a,b) -> (f a, g b)<br />
flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
<br />
> unpl flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
(\ aa f -><br />
(\ p w -> ((,)) (aa (fst p)) (f w)) >>=<br />
\ ao -> snd >>= \ an -> return (ao an))<br />
</haskell><br />
<br />
== Combinator discoveries ==<br />
<br />
Some fun combinators have been found via @pl. Here we list some of the<br />
best:<br />
<br />
=== The owl ===<br />
<br />
<haskell><br />
((.)$(.))<br />
</haskell><br />
<br />
The owl has type <hask>(a -> b -> c) -> a -> (a1 -> b) -> a1 -><br />
c</hask>, and in pointful style can be written as <hask> f a b c d = a b<br />
(c d)</hask>.<br />
<br />
Example <br />
<haskell><br />
> ((.)$(.)) (==) 1 (1+) 0<br />
True<br />
</haskell><br />
<br />
=== Dot ===<br />
<br />
<haskell><br />
dot = ((.).(.))<br />
<br />
dot :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
sequence `dot` replicate == <br />
(sequence .) . replicate ==<br />
replicateM<br />
<br />
(=<<) == join `dot` fmap<br />
</haskell><br />
<br />
=== Swing ===<br />
<br />
-- Note: @pl had nothing to do with the invention of this combinator. I constructed it by hand after noticing a common pattern. -- Cale<br />
<br />
<haskell><br />
swing :: (((a -> b) -> b) -> c -> d) -> c -> a -> d<br />
swing = flip . (. flip id)<br />
swing f = flip (f . runCont . return)<br />
swing f c a = f ($ a) c<br />
</haskell><br />
<br />
Some examples of use:<br />
<br />
<haskell><br />
swing map :: forall a b. [a -> b] -> a -> [b]<br />
swing any :: forall a. [a -> Bool] -> a -> Bool<br />
swing foldr :: forall a b. b -> a -> [a -> b -> b] -> b<br />
swing zipWith :: forall a b c. [a -> b -> c] -> a -> [b] -> [c]<br />
swing find :: forall a. [a -> Bool] -> a -> Maybe (a -> Bool)<br />
-- applies each of the predicates to the given value, returning the first predicate which succeeds, if any<br />
swing partition :: forall a. [a -> Bool] -> a -> ([a -> Bool], [a -> Bool])<br />
</haskell><br />
<br />
=== Squish ===<br />
<br />
<haskell><br />
f >>= a . b . c =<< g<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
(readFile y >>=) . ((a . b) .) . c =<< readFile x<br />
</haskell><br />
<br />
[[/Combine|An actually useful example]], numbering lines of a file.<br />
<br />
== Problems with pointfree ==<br />
<br />
Point-free style can (clearly) lead to [[Obfuscation]] when used unwisely.<br />
As higher-order functions are chained together, it can become harder to<br />
mentally infer the types of expressions. The mental cues to an<br />
expression's type (explicit function arguments, and the number of<br />
arguments) go missing.<br />
<br />
Point-free style often times leads to code which is difficult to modify. A function written in a pointfree style may have to be radically changed to make minor changes in functionality. This is because the function becomes more complicated than a composition of lambdas and other functions, and compositions must be changed to application for a pointful function.<br />
<br />
Perhaps these are why pointfree style is sometimes (often?) referred to as<br />
''pointless style''.<br />
<br />
== References ==<br />
<br />
One early reference is<br />
<br />
* Backus, J. 1978. "Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs," Communications of the Association for Computing Machinery 21:613-641.<br />
<br />
which appears to be available (as a scan) at http://www.stanford.edu/class/cs242/readings/backus.pdf<br />
<br />
A paper specifically about point-free style: <br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#radix<br />
<br />
This style underlies a lot of expert Haskeller's intuitions. <br />
A rather infamous paper (for all the cute symbols) is Erik Meijer et. al's:<br />
<br />
* Functional Programming with Bananas, Lenses, and Barbed Wire, http://wwwhome.cs.utwente.nl/~fokkinga/mmf91m.ps.<br />
<br />
[http://en.wikipedia.org/wiki/Squiggol Squiggol], and the Bird-Meertens Formalism:<br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#squiggolintro.<br />
* A Calculus of Functions for Program Derivation, R.S. Bird, in Res Topics in Fnl Prog, D. Turner ed, A-W 1990.<br />
* The Squiggolist, ed Johan Jeuring, published irregularly by CWI Amsterdam.<br />
<br />
[http://wiki.di.uminho.pt/twiki/bin/view/Personal/Alcino/PointlessHaskell Pointless Haskell] is a library for point-free programming with recursion patterns defined as hylomorphisms. It also allows the visualization of the intermediate data structure of the hylomorphisms with GHood. This feature together with the DrHylo tool allows us to easily visualize recursion trees of Haskell functions. [http://wiki.di.uminho.pt/wiki/pub/Ze/Bic/report.pdf Haskell Manipulation] by Jose Miguel Paiva Proenca discusses this tool based approach to re-factoring.<br />
<br />
This project is written by [http://www.di.uminho.pt/~mac/ Manuel Alcino Cunha], see his homepage for more related materials on the topic.<br />
An extended verson of his paper ''Point-free Programming with Hylomorphisms'' can be found [http://web.comlab.ox.ac.uk/oucl/research/pdt/ap/dgp/workshop2004/cunha.pdf here].<br />
<br />
== Other areas ==<br />
<br />
[[Combinatory logic]] and also [[Recursive function theory]] can be said in some sense pointfree.<br />
<br />
Are there pointfree approaches to [[relational algebra]]?<br />
See [http://www.di.uminho.pt/~jno/ps/_.pdf First Steps in Pointfree Functional Dependency Theory] written by Jos Nuno Oliveira. A concise and deep approach. See also [http://www.di.uminho.pt/~jno/html/ the author's homepage] and also [http://www.di.uminho.pt/~jno/html/jnopub.html his many other papers] -- many materials related to this topic can be found there.<br />
<br />
[[Category:Idioms]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Applications_and_libraries/Mathematics&diff=31139
Applications and libraries/Mathematics
2009-10-26T02:45:22Z
<p>CaleGibbard: </p>
<hr />
<div>== Applications ==<br />
<br />
=== Physics ===<br />
<br />
;[http://ab-initio.mit.edu/meep/ Meep]<br />
:Meep (or MEEP) is a free finite-difference time-domain (FDTD) simulation software package developed at MIT to model electromagnetic systems.<br />
<br />
;[[Numeric Quest]]<br />
:Jan Skibinski's [[Numeric Quest]] library provides modules that are useful for Quantum Mechanics, among other things.<br />
<br />
== Libraries ==<br />
<br />
=== Linear algebra ===<br />
<br />
;[http://www.cs.utah.edu/~hal/HBlas/index.html Wrapper to CLAPACK]<br />
<br />
;[http://haskelldsp.sourceforge.net/ Digital Signal Processing]<br />
:Modules for matrix manipulation, Fourier transform, interpolation, spectral estimation, and frequency estimation.<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.general/13561 Index-aware linear algebra]<br />
:Frederik Eaton's library for statically checked matrix manipulation in Haskell<br />
<br />
;[[Numeric Quest]]<br />
:Jan Skibinski's [[Numeric Quest]] library provides several modules that are useful for linear algebra in general, among other things.<br />
<br />
;[[vector-space]]<br />
:The [[vector-space]] package defines classes and generic operations for vector spaces and affine spaces. It also defines a type of infinite towers of generalized derivatives (linear transformations).<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hmatrix HMatrix]<br />
:By Alberto Ruiz. From the project [http://www.hmatrix.googlepages.com/ website]:<br />
::''This library provides a purely functional interface to linear algebra and other numerical computations, internally implemented using GSL, BLAS and LAPACK.''<br />
<br />
::''All linear algebra functions mentioned in GNU-Octave's Quick Reference (except syl) are already available both for real and complex matrices: eig, svd, chol, qr, hess, schur, inv, pinv, expm, norm, and det. There are also functions for numeric integration and differentiation, nonlinear minimization, polynomial root finding, etc.''<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Vec Vec]<br />
:By Scott E. Dillard. Static dimension checking:<br />
::''Vectors are represented by lists with type-encoded lengths. The constructor is :., which acts like a cons both at the value and type levels, with () taking the place of nil. So x:.y:.z:.() is a 3d vector. The library provides a set of common list-like functions (map, fold, etc) for working with vectors. Built up from these functions are a small but useful set of linear algebra operations: matrix multiplication, determinants, solving linear systems, inverting matrices.''<br />
<br />
== See also ==<br />
<br />
* [[Linear algebra]]<br />
* [[Mathematical prelude discussion]]<br />
<br />
<br />
See also: [[Linear algebra|Design discussions]]<br />
<br />
=== [[Physical units]] ===<br />
<br />
;[[Dimensionalized numbers]]<br />
: Working with physical units like second, meter and so on in a type-safe manner.<br />
<br />
;[http://darcs.haskell.org/numericprelude/src/Number/SI.hs NumericPrelude: Physical units]<br />
: Numeric values with dynamically checked units.<br />
<br />
;[[CalDims]]<br />
:This is not simply a library providing a new type of <hask>Num</hask> class, but stand-alone calculation tool that supports user defined functions and units (basic and derrived), so it can provide dimension-save calculation (not embedded but via shell). Calculations can be modified/saved via shell. It uses rational numbers to avoid rounding errors where possible.<br />
<br />
;[http://code.google.com/p/dimensional/ Dimensional]<br />
: Library providing data types for performing arithmetic with physical quantities and units. Information about the physical dimensions of the quantities/units is embedded in their types and the validity of operations is verified by the type checker at compile time. The boxing and unboxing of numerical values as quantities is done by multiplication and division of units.<br />
<br />
=== Number representations ===<br />
<br />
==== Decimal numbers ====<br />
<br />
;[http://src.seereason.com/decimal/ Decimal arithmetic library]<br />
:An implementation of real decimal arithmetic, for cases where the binary floating point is not acceptable (for example, money).<br />
<br />
==== Real and rational numbers ====<br />
<br />
There are several levels of [[Exact real arithmetic|handling real numbers]] and according libraries.<br />
<br />
===== Arbitrary precision =====<br />
<br />
* Numbers have fixed precision<br />
* Rounding errors accumulate<br />
* Sharing is easy, i.e. in <hask>sqrt pi + sin pi</hask>, <hask>pi</hask> is computed only once<br />
* Fast, because the routines can make use of the fast implementation of <hask>Integer</hask> operations<br />
<br />
;[[Numeric Quest]]<br />
:Jan Skibinski's [[Numeric Quest]] library provides, among other things, a type for arbitrary precision rational numbers with transcendental functions.<br />
<br />
;[http://cvs.haskell.org/darcs/numericprelude/src/Number/FixedPoint.hs FixedPoint.hs]<br />
:part of NumericPrelude project<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/AERN-Real AERN-Real]<br />
:contains arbitrary precision ''interval arithmetic'' for approximating exact real numbers in a style similar to Mueller's iRRAM and Lambov's RealLib<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/AERN-RnToRm AERN-RnToRm]<br />
:contains arithmetic of ''piecewise polynomial function enclosures'' that efficiently approximate multi-dimensional real functions to arbitrary precision<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hmpfr hmpfr]<br />
:hmpfr is a purely functional haskell interface to the [http://www.mpfr.org/ MPFR] library<br />
<br />
===== Dynamic precision =====<br />
<br />
* You tell the precision, an expression shall be computed to and the computer finds out, how precise to compute the input values.<br />
* Rounding errors do not accumulate<br />
* Sharing of temporary results is difficult, that is in <hask>sqrt pi + sin pi</hask>, <hask>pi</hask> will certainly be computed twice, each time with the required precision.<br />
* Almost as fast as arbitrary precision computation<br />
<br />
;[http://www.cs.man.ac.uk/arch/dlester/exact.html ERA] is an implementation (in Haskell 1.2) by David Lester.<br />
: It is quite fast, possibly the fastest Haskell implementation. At 220 lines it is also the shortest. Probably the shortest implementation of exact real arithmetic in any language.<br />
: The provided number type <hask>CReal</hask> is instance of the Haskell 98 numeric type classes and thus can be used whereever you used Float or Double before and encountered some numerical difficulties.<br />
:Here is a mirror: http://darcs.augustsson.net/Darcs/CReal/<br />
<br />
;[http://www.doc.ic.ac.uk/~ae/exact-computation/#bm:implementations IC-Reals] is an implementation by Abbas Edalat, Marko Krznar&#263; and Peter J. Potts.<br />
:This implementation uses linear fractional transformations.<br />
<br />
;[http://r6.ca/ Few Digits] by Russell O'Connor.<br />
:This is a prototype of the implementation he intendeds to write in [http://coq.inria.fr/ Coq]. Once the Coq implementation is complete, the Haskell code could be extracted producing an implementation that would be proved correct.<br />
<!--<br />
Example:<br />
*Data.Real.CReal> answer 1000 (exp 1 + sqrt 2)<br />
--><br />
<br />
;COMP is an implementation by Yann Kieffer.<br />
:The work is in beta and relies on new primitive operations on Integers which will be implemented in GHC. The library isn't available yet.<br />
<br />
;[http://www2.arnes.si/~abizja4/hera/ Hera] is an implementation by Aleš Bizjak.<br />
:It uses the [http://www.mpfr.org/ MPFR] library to implement dyadic rationals, on top of which are implemented intervals and real numbers. A real number is represented as a function <code>int -&gt; interval</code> which represents a sequence of intervals converging to the real.<br />
<br />
===== Dynamic precision by lazy evaluation =====<br />
<br />
The real numbers are represented by an infinite datastructure, which allows you to increase precision successively by evaluating the data structure successively. All of the implementations below use some kind of digit stream as number representation.<br />
Sharing of results is simple.<br />
The implementations are either fast on simple expressions, because they use large blocks/bases, or they are fast on complex expressions, because they consume as little as possible input digits in order to emit the required output digits.<br />
<br />
;[http://medialab.freaknet.org/bignum/ BigFloat] is an implementation by Martin Guy.<br />
:It works with streams of decimal digits (strictly in the range from 0 to 9) and a separate sign. The produced digits are always correct. Output is postponed until the code is certain what the next digit is. This sometimes means that [http://medialab.freaknet.org/bignum/dudeney.html no more data is output].<br />
<br />
;In [http://users.info.unicaen.fr/~karczma/arpap/lazypi.ps.gz "The Most Unreliable Technique in the World to compute pi"] Jerzy Karczmarczuk develops some functions for computing pi lazily.<br />
<br />
;[http://darcs.haskell.org/numericprelude/src/Number/Positional.hs NumericPrelude: positional numbers]<br />
:Represents a real number as pair <hask>(exponent,[digit])</hask>, where the digits are <hask>Int</hask>s in the open range <hask>(-basis,basis)</hask>. There is no need for an extra sign item in the number data structure. The <hask>basis</hask> can range from <hask>10</hask> to <hask>1000</hask>. (Binary representations can be derived from the hexadecimal representation.) Showing the numbers in traditional format (non-negative digits) fails for fractions ending with a run of zeros. However the internal representation with negative digits can always be shown and is probably more useful for further processing. An interface for the numeric type hierarchy of the NumericPrelude project is provided.<br />
:It features<br />
:* basis conversion<br />
:* basic arithmetic: addition, subtraction, multiplication, division<br />
:* algebraic arithmetic: square root, other roots (no general polynomial roots)<br />
:* transcendental arithmetic: pi, exponential, logarithm, trigonometric and inverse trigonometric functions<br />
<br />
=== Type class hierarchies ===<br />
<br />
There are several approaches to improve the [[Mathematical prelude discussion|numeric type class hierarchy]].<br />
<br />
;Dylan Thurston and Henning Thielemann's [[Numeric Prelude]]<br />
:Experimental revised framework for numeric type classes. Needs hiding of Prelude, overriding hidden functions like fromInteger and multi-parameter type classes. Probably restricted to GHC.<br />
<br />
;Jerzy Karczmarczuk's [http://www.haskell.org/pipermail/haskell-cafe/2001-February/001510.html approach]<br />
<br />
;Serge D. Mechveliani's [ftp://ftp.botik.ru/pub/local/Mechveliani/basAlgPropos/ Basic Algebra proposal]<br />
<br />
;Andrew Frank's [http://www.haskell.org/pipermail/haskell-cafe/2006-April/015326.html approach]<br />
:The proposal: ftp://ftp.geoinfo.tuwien.ac.at/frank/numbersPrelude_v1.pdf<br />
<br />
;Haskell Prime: [http://hackage.haskell.org/trac/haskell-prime/ticket/112 Ongoing efforts for the language revision]<br />
<br />
=== Discrete mathematics ===<br />
<br />
;[http://andrew.bromage.org/darcs/numbertheory/ Number Theory Library]<br />
:Andrew Bromage's Haskell number theory library, providing operations on primes, fibonacci sequences and combinatorics.<br />
<br />
;[http://users.skynet.be/jyp/HGAL/ HGAL]<br />
:An haskell implementation of Brendan McKay's algorithm for graph canonic labeling and automorphism group. (aka Nauty)<br />
<br />
;[http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=0521849306 Computational Oriented Matroids]<br />
:is a book by [http://wwwopt.mathematik.tu-darmstadt.de/~bokowski/ Jürgen G. Bokowski], where he develops Haskell code for Matroid computations.<br />
<br />
See also [[Libraries and tools/Cryptography]]<br />
<br />
=== Computer Algebra ===<br />
<br />
;[http://haskell.org/docon/ DoCon] - Algebraic Domain Constructor<br />
:A library for Algebra, turns GHCi into a kind of Computer Algebra System<br />
<br />
;[http://www.info.unicaen.fr/~karczma/arpap/ Papers by Jerzy Karczmarczuk]<br />
:Some interesting uses of Haskell in mathematics, including [[functional differentiation]], power series, continued fractions.<br />
<br />
=== Statistics ===<br />
;[http://www.sftank.net/?q=node/10 hstats]<br />
: Statistical Computing with Haskell<br />
<br />
=== Plotting ===<br />
<br />
;[[Gnuplot]]<br />
: Simple wrapper to gnuplot<br />
<br />
;[http://alberrto.googlepages.com/gslhaskell GSLHaskell]<br />
: gnuplot wrapper as part of GSL Haskell package<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Chart Chart]<br />
: A library for generating 2D Charts and Plots, based upon the cairo graphics library.<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/probability probability]<br />
: the module Numeric.Probability.Visualize contains a wrapper to [http://www.r-project.org/ R]<br />
<br />
=== Miscellaneous libraries ===<br />
<br />
;[http://www.robtougher.com/HaskellMath/ HaskellMath]<br />
:The HaskellMath library is a sandbox for experimenting with mathematics algorithms. So far I've implemented a few quantitative finance models (Black Scholes, Binomial Trees, etc) and basic linear algebra functions. Next I might work on either computer algebra or linear programming. All comments welcome!<br />
<br />
;[http://www.polyomino.f2s.com/david/haskell/codeindex.html Haskell for Maths]<br />
:David Amos' [http://www.polyomino.f2s.com/david/haskell/main.html collection of math libraries] in Haskell - including number theory, commutative algebra, combinatorics, permutation groups and more.<br />
<br />
;[http://darcs.haskell.org/htam/ Various math stuff by Henning Thielemann]<br />
:This is some unsorted mathematical stuff including: gnuplot wrapper (now maintained as separate package), portable grey map (PGM) image reader and writer, simplest numerical integration, differentiation, zero finding, interpolation, solution of differential equations, combinatorics, some solutions of math riddles, computation of fractal dimensions of iterated function systems (IFS)<br />
<br />
;[[Numeric Quest]]<br />
:Jan Skibinski wrote a collection of Haskell modules that are useful for Mathematics in general, and Quantum Mechanics in particular.<br />
<br />
:Some of the modules are hosted on [http://darcs.haskell.org/numeric-quest/ haskell.org]. They include modules for:<br />
:* Rational numbers with transcendental functions<br />
:* Roots of polynomials<br />
:* Eigensystems<br />
:* Tensors<br />
:* Dirac quantum mechanics<br />
<br />
:Other modules in Numeric Quest are currently only available via the [http://web.archive.org/web/20010605003250/http://www.numeric-quest.com/haskell/ Internet Archive]. They include, among many other things:<br />
:* [http://web.archive.org/web/*/http://www.numeric-quest.com/haskell/ State vector evolution]<br />
:* [http://web.archive.org/web/*/http://www.numeric-quest.com/haskell/ Short study of fuzzy oscillator]<br />
<br />
:See the [[Numeric Quest]] page for more information.<br />
<br />
;[http://www.dinkla.net/fp/cglib.html Geometric Algorithms]<br />
:A small Haskell library, containing algorithms for two-dimensional convex hulls, triangulations of polygons, Voronoi-diagrams and Delaunay-triangulations, the QEDS data structure, kd-trees and range-trees.<br />
<br />
;[http://repetae.net/john/recent/out/HsASA.html Adaptive Simulated Annealing]<br />
:A Haskell interface to Lester Ingber's adaptive simulating annealing code.<br />
<br />
;[http://home.solcon.nl/mklooster/repos/hmm/ Hmm: Haskell Metamath]<br />
:Hmm is a small Haskell library to parse and verify Metamath databases.<br />
<br />
;[[Probabilistic Functional Programming]]<br />
:The PFP library is a collection of modules for Haskell that facilitates probabilistic functional programming, that is, programming with stochastic values. The probabilistic functional programming approach is based on a data type for representing distributions. A distribution represent the outcome of a probabilistic event as a collection of all possible values, tagged with their likelihood. A nice aspect of this system is that simulations can be specified independently from their method of execution. That is, we can either fully simulate or randomize any simulation without altering the code which defines it.<br />
<br />
;[[Sinc function]]<br />
<br />
;[[Gamma and Beta function]]<br />
<br />
;[http://repetae.net/john/recent/out/Boolean.html Boolean]<br />
:A general boolean algebra class and some instances for Haskell.<br />
<br />
;[http://darcs.haskell.org/~lemmih/hode/ HODE]<br />
:HODE is a binding to the Open Dynamics Engine. ODE is an open source, high performance library for simulating rigid body dynamics.<br />
<br />
;[http://sourceforge.net/projects/ranged-sets Ranged Sets]<br />
:A ranged set is a list of non-overlapping ranges. The ranges have upper and lower boundaries, and a boundary divides the base type into values above and below. No value can ever sit on a boundary. So you can have the set <math>(2.0, 3.0] \cup (5.3, 6)</math>.<br />
<br />
;[http://code.google.com/p/hhydra/ hhydra]<br />
:Hhydra is a tool to compute Goodstein successions and hydra puzzles described by Bernard Hodgson in his article 'Herculean or Sisyphean tasks?' published in No 51 March 2004 of the Newsletter of the European Mathematical Society.<br />
<br />
[[Category:Mathematics|*]]<br />
{{LibrariesPage}}</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Power_function&diff=29563
Power function
2009-08-15T15:28:12Z
<p>CaleGibbard: </p>
<hr />
<div>== Question ==<br />
<br />
Why are there several notions of power in Haskell, namely <hask>(^)</hask>, <hask>(^^)</hask>, <hask>(**)</hask>?<br />
<br />
<br />
== Answer ==<br />
<br />
The reason is that there is no definition for the power function which covers all exotic choices for basis and exponent.<br />
It is even sensible to refine the set of power functions as it is done in the [[Numeric Prelude]] project.<br />
In mathematical notation we don't respect types and we do not distinguish between powers of different types.<br />
However if we assume the most general types for both basis and exponent, the result of the power is no longer unique.<br />
Actually all possible solutions of say <math>1^x</math>,<br />
where <math>x</math> is irrational is dense in the complex unit circle.<br />
In the past I needed the power of two complex numbers only once, namely for the [http://www.math.uni-bremen.de/~thielema/Research/cwt.pdf Cauchy wavelet] (see also: [http://ieeexplore.ieee.org/iel5/78/18506/00852022.pdf?arnumber=852022]):<br />
: <math> f(t) = (1- i\cdot k\cdot t) ^ {-\frac{1}{2} + \frac{\mu_2}{k} + i\cdot \mu_1 } </math><br />
However, I could not use the built-in complex power function<br />
because the resulting function became discontinuous.<br />
Of course, powers of complex numbers have the problem of branch cuts and<br />
the choice of the branch built into the implementation of the complex power is quite arbitrary and<br />
might be inappropriate.<br />
<br />
But also for real numbers there are problems:<br />
For computing <hask>(-1)**(1/3::Double)</hask> the power implementation would have to decide whether <br />
<hask>(1/3::Double)</hask> is close enough to <math>\frac{1}{3}</math>.<br />
If it does so it returns <hask>(-1)</hask>, otherwise it fails.<br />
However, why shall <hask>0.333333333333333</hask> represent <math>\frac{1}{3}</math>?<br />
It may be really meant as <hask>333333333333333/10^15</hask>,<br />
and a real <math>10^{15}</math>th root of <math>-1</math> does not exist.<br />
Fortunately, the Haskell implementation does not try to be too clever here.<br />
But it does so at another point:<br />
<haskell><br />
Prelude> (-1)**2 :: Double<br />
1.0<br />
Prelude> (-1)**(2 + 1e-15 - 1e-15) :: Double<br />
NaN<br />
</haskell><br />
Of course, both expressions should be evaluated to <hask>1.0</hask>,<br />
but a reliable check for integers is not possible with floating point numbers.<br />
<br />
So I propose some balancing: The more general the basis the less general the exponent and vice versa.<br />
I also think the following symbols are more systematic and intuitive.<br />
They are used in NumericPrelude.<br />
{|<br />
| basis type || provides || symbol || exponent type || definition ||<br />
|-<br />
| any ring || <hask> * </hask> || <hask> ^ </hask> || cardinal || repeated multiplication || <math>a^b = \prod_{i=1}^b a </math><br />
|-<br />
| any field || <hask> / </hask> || <hask> ^- </hask> || integer || multiplication and division || <math>a^b = \begin{cases} a^b & b\ge 0 \\ \frac{1}{a^{-b}} & b<0 \end{cases} </math><br />
|-<br />
| an algebraic field || <hask>root</hask> || <hask> ^/ </hask> || rational || list of polynomial zeros (length = denominator of the exponent) || <math> a^{\frac{p}{q}} = \{ x : a^p = x^q \} </math><br />
|-<br />
| positive real || <hask> log </hask> || ^? || any ring of characteristic zero with inverses for integers and a notion of limit || exponential series and logarithm || <math>a^b = \exp(b \log a) = \sum_{k \geq 0} \frac{(b \log a)^k}{k!}</math><br />
|}<br />
<br />
* examples for rings are: Polynomials, Matrices, Residue classes<br />
* examples for fields: Fractions of polynomials (rational functions), Residue classes with respect to irreducible divisors, in fact we do not need fields, we only need the division and associativity, thus invertible Matrices are fine<br />
<br />
<br />
That is <hask>(^-)</hask> replaces <hask>(^^)</hask>,<br />
<hask>(^?)</hask> replaces <hask>(**)</hask>,<br />
<hask>(^)</hask> remains and <hask>(^/)</hask> is new.<br />
<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2006-April/015329.html Proposal for restructuring Number classes]<br />
<br />
[[Category:Mathematics]]<br />
[[Category:FAQ]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Pointfree&diff=29266
Pointfree
2009-07-27T01:41:09Z
<p>CaleGibbard: </p>
<hr />
<div>__TOC__<br />
<br />
'''Pointfree Style'''<br />
<br />
It is very common for functional programmers to write functions as a<br />
composition of other functions, never mentioning the actual arguments<br />
they will be applied to. For example, compare:<br />
<br />
<haskell><br />
sum = foldr (+) 0<br />
</haskell><br />
<br />
with:<br />
<br />
<haskell><br />
sum' xs = foldr (+) 0 xs<br />
</haskell><br />
<br />
These functions perform the same operation, however, the former is more<br />
compact, and is considered cleaner. This is closely related to function<br />
pipelines (and to [http://www.vex.net/~trebla/weblog/pointfree.html unix shell scripting]<br />
): it is clearer to write <hask>let fn = f . g . h</hask> than to<br />
write <hask>let fn x = f (g (h x))</hask>.<br />
<br />
This style is particularly useful when deriving efficient programs by<br />
calculation and, in general, constitutes good discipline. It helps the writer<br />
(and reader) think about composing functions (high level), rather than<br />
shuffling data (low level).<br />
<br />
It is a common experience when rewriting expressions in pointfree style<br />
to derive more compact, clearer versions of the code -- explicit points<br />
often obscure the underlying algorithm.<br />
<br />
Point-free map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr (f . g) e<br />
</haskell><br />
<br />
versus pointful map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr f' e<br />
where f' a b = f (g a) b<br />
</haskell><br />
<br />
Some more examples:<br />
<br />
<haskell><br />
-- point-wise, and point-free member<br />
mem, mem' :: Eq a => a -> [a] -> Bool<br />
<br />
mem x lst = any (== x) lst<br />
mem' = any . (==)<br />
</haskell><br />
<br />
== But pointfree has more points! ==<br />
<br />
A common misconception is that the 'points' of pointfree style are the<br />
<hask>(.)</hask> operator (function composition, as an ASCII symbol),<br />
which uses the same identifier as the decimal point. This is wrong. The<br />
term originated in topology, a branch of mathematics which works with<br />
spaces composed of points, and functions between those spaces. So a<br />
'points-free' definition of a function is one which does not explicitly<br />
mention the points (values) of the space on which the function acts. In<br />
Haskell, our 'space' is some type, and 'points' are values. In the<br />
declaration:<br />
<haskell><br />
f x = x + 1<br />
</haskell><br />
we define the function <hask>f</hask> in terms of its action on an<br />
arbitrary point <hask>x</hask>. Contrast this with the points-free<br />
version:<br />
<haskell><br />
f = (+ 1)<br />
</haskell><br />
where there is no mention of the value on which the function is acting.<br />
<br />
== Background ==<br />
<br />
To find out more about this style, search for Squiggol and the<br />
Bird-Meertens Formalism, a style of functional programming by<br />
calculation that was developed by [http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications.html Richard Bird], [http://www.kestrel.edu/home/people/meertens/ Lambert Meertens], and<br />
others at Oxford University. [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/ Jeremy Gibbons] has also written a number of<br />
papers about the topic, which are cited below.<br />
<br />
== Tool support ==<br />
<br />
Thomas Yaeger has<br />
[http://www.cse.unsw.edu.au/~dons/code/lambdabot/Plugins/Pl/ written] a <br />
[http://www.cse.unsw.edu.au/~dons/lambdabot.html Lambdabot] <br />
plugin to automatically convert a large subset of Haskell expressions to<br />
pointfree form. This tool has made it easier to use the more abstract<br />
pointfree encodings (as it saves some mental gymnastics on the part of<br />
the programmer). You can experiment with this in the [[IRC channel|Haskell IRC channel]]. A stand-alone command-line version is available at [http://hackage.haskell.org/packages/archive/pkg-list.html HackageDB] (package pointfree).<br />
<br />
The @pl (point-less) plugin is rather infamous for using the <hask>(->) a</hask> <br />
[[Monad|monad]] to obtain concise code. It also makes use of [[Arrow|Arrows]]. <br />
It also sometimes produces (amusing) code blow ups with the<br />
<hask>(.)</hask> operator. Recently, @unpl has been written, which<br />
(attempts) to unscramble @pl-ified code.<br />
<br />
A transcript:<br />
<br />
<haskell><br />
> pl \x y -> x y<br />
id<br />
<br />
> unpl id<br />
(\ a -> a)<br />
<br />
> pl \x y -> x + 1<br />
const . (1 +)<br />
<br />
> unpl const . (1 +)<br />
(\ e _ -> 1 + e)<br />
<br />
> pl \v1 v2 -> sum (zipWith (*) v1 v2)<br />
(sum .) . zipWith (*)<br />
<br />
> unpl (sum .) . zipWith (*)<br />
(\ d g -> sum (zipWith (*) d g))<br />
<br />
> pl \x y z -> f (g x y z)<br />
((f .) .) . g<br />
<br />
> unpl ((f .) .) . g<br />
(\ e j m -> f (g e j m))<br />
<br />
> pl \x y z -> f (g x y) z<br />
(f .) . g<br />
<br />
> unpl (f .) . g<br />
(\ d i -> f (g d i))<br />
<br />
> pl \x y z -> f z (g x y)<br />
(flip f .) . g<br />
<br />
> unpl (flip f .) . g<br />
(\ i l c -> f c (g i l))<br />
<br />
> pl \(a,b) -> (b,a)<br />
uncurry (flip (,))<br />
<br />
> pl f a b = b a<br />
f = flip id<br />
<br />
> pl \ x -> x * x<br />
join (*)<br />
<br />
> pl \a b -> a:b:[]<br />
(. return) . (:)<br />
<br />
> pl \x -> x+x+x<br />
(+) =<< join (+)<br />
<br />
> pl \a b -> Nothing<br />
const (const Nothing)<br />
<br />
> pl \(a,b) -> (f a, g b)<br />
f *** g<br />
<br />
> pl \f g h x -> f x `h` g x<br />
flip . (ap .) . flip (.)<br />
<br />
> pl \x y -> x . f . y<br />
(. (f .)) . (.)<br />
<br />
> pl \f xs -> xs >>= return . f<br />
fmap<br />
<br />
> pl \h f g x -> f x `h` g x<br />
liftM2<br />
<br />
> pl \f a b c d -> f b c d a<br />
flip . ((flip . (flip .)) .)<br />
<br />
> pl \a (b,c) -> a c b<br />
(`ap` snd) . (. fst) . flip<br />
<br />
> pl \x y -> compare (f x) (f y)<br />
((. f) . compare .)<br />
</haskell><br />
<br />
For many many more examples, google for the results of '@pl' in the<br />
[[IRC_channel|#haskell]] logs. (Or join #haskell on FreeNode and try it<br />
yourself!) It can, of course, get out of hand:<br />
<br />
<haskell><br />
> pl \(a,b) -> a:b:[]<br />
uncurry ((. return) . (:))<br />
<br />
> pl \a b c -> a*b+2+c<br />
((+) .) . flip flip 2 . ((+) .) . (*)<br />
<br />
> pl \f (a,b) -> (f a, f b)<br />
(`ap` snd) . (. fst) . (flip =<< (((.) . (,)) .))<br />
<br />
> pl \f g (a,b) -> (f a, g b)<br />
flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
<br />
> unpl flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
(\ aa f -><br />
(\ p w -> ((,)) (aa (fst p)) (f w)) >>=<br />
\ ao -> snd >>= \ an -> return (ao an))<br />
</haskell><br />
<br />
== Combinator discoveries ==<br />
<br />
Some fun combinators have been found via @pl. Here we list some of the<br />
best:<br />
<br />
=== The owl ===<br />
<br />
<haskell><br />
((.)$(.))<br />
</haskell><br />
<br />
The owl has type <hask>(a -> b -> c) -> a -> (a1 -> b) -> a1 -><br />
c</hask>, and in pointful style can be written as <hask> f a b c d = a b<br />
(c d)</hask>.<br />
<br />
Example <br />
<haskell><br />
> ((.)$(.)) (==) 1 (1+) 0<br />
True<br />
</haskell><br />
<br />
=== Dot ===<br />
<br />
<haskell><br />
dot = ((.).(.))<br />
<br />
dot :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
sequence `dot` replicate == <br />
(sequence .) . replicate ==<br />
replicateM<br />
<br />
(=<<) == join `dot` fmap<br />
</haskell><br />
<br />
=== Swing ===<br />
<br />
-- Note: @pl had nothing to do with the invention of this combinator. I constructed it by hand after noticing a common pattern. -- Cale<br />
<br />
<haskell><br />
swing :: (((a -> b) -> b) -> c -> d) -> c -> a -> d<br />
swing = flip . (. flip id)<br />
swing f c a = f ($ a) c<br />
</haskell><br />
<br />
Some examples of use:<br />
<br />
<haskell><br />
swing map :: forall a b. [a -> b] -> a -> [b]<br />
swing any :: forall a. [a -> Bool] -> a -> Bool<br />
swing foldr :: forall a b. b -> a -> [a -> b -> b] -> b<br />
swing zipWith :: forall a b c. [a -> b -> c] -> a -> [b] -> [c]<br />
swing find :: forall a. [a -> Bool] -> a -> Maybe (a -> Bool)<br />
-- applies each of the predicates to the given value, returning the first predicate which succeeds, if any<br />
swing partition :: forall a. [a -> Bool] -> a -> ([a -> Bool], [a -> Bool])<br />
</haskell><br />
<br />
=== Squish ===<br />
<br />
<haskell><br />
f >>= a . b . c =<< g<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
(readFile y >>=) . ((a . b) .) . c =<< readFile x<br />
</haskell><br />
<br />
[[/Combine|An actually useful example]], numbering lines of a file.<br />
<br />
== Problems with pointfree ==<br />
<br />
Point-free style can (clearly) lead to [[Obfuscation]] when used unwisely.<br />
As higher-order functions are chained together, it can become harder to<br />
mentally infer the types of expressions. The mental cues to an<br />
expression's type (explicit function arguments, and the number of<br />
arguments) go missing.<br />
<br />
Point-free style often times leads to code which is difficult to modify. A function written in a pointfree style may have to be radically changed to make minor changes in functionality. This is because the function becomes more complicated than a composition of lambdas and other functions, and compositions must be changed to application for a pointful function.<br />
<br />
Perhaps these are why pointfree style is sometimes (often?) referred to as<br />
''pointless style''.<br />
<br />
== References ==<br />
<br />
One early reference is<br />
<br />
* Backus, J. 1978. "Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs," Communications of the Association for Computing Machinery 21:613-641.<br />
<br />
which appears to be available (as a scan) at http://www.stanford.edu/class/cs242/readings/backus.pdf<br />
<br />
A paper specifically about point-free style: <br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#radix<br />
<br />
This style underlies a lot of expert Haskeller's intuitions. <br />
A rather infamous paper (for all the cute symbols) is Erik Meijer et. al's:<br />
<br />
* Functional Programming with Bananas, Lenses, and Barbed Wire, http://wwwhome.cs.utwente.nl/~fokkinga/mmf91m.ps.<br />
<br />
[http://en.wikipedia.org/wiki/Squiggol Squiggol], and the Bird-Meertens Formalism:<br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#squiggolintro.<br />
* A Calculus of Functions for Program Derivation, R.S. Bird, in Res Topics in Fnl Prog, D. Turner ed, A-W 1990.<br />
* The Squiggolist, ed Johan Jeuring, published irregularly by CWI Amsterdam.<br />
<br />
[http://wiki.di.uminho.pt/twiki/bin/view/Personal/Alcino/PointlessHaskell Pointless Haskell] is a library for point-free programming with recursion patterns defined as hylomorphisms. It also allows the visualization of the intermediate data structure of the hylomorphisms with GHood. This feature together with the DrHylo tool allows us to easily visualize recursion trees of Haskell functions. [http://wiki.di.uminho.pt/wiki/pub/Ze/Bic/report.pdf Haskell Manipulation] by Jose Miguel Paiva Proenca discusses this tool based approach to re-factoring.<br />
<br />
This project is written by [http://www.di.uminho.pt/~mac/ Manuel Alcino Cunha], see his homepage for more related materials on the topic.<br />
An extended verson of his paper ''Point-free Programming with Hylomorphisms'' can be found [http://web.comlab.ox.ac.uk/oucl/research/pdt/ap/dgp/workshop2004/cunha.pdf here].<br />
<br />
== Other areas ==<br />
<br />
[[Combinatory logic]] and also [[Recursive function theory]] can be said in some sense pointfree.<br />
<br />
Are there pointfree approaches to [[relational algebra]]?<br />
See [http://www.di.uminho.pt/~jno/ps/_.pdf First Steps in Pointfree Functional Dependency Theory] written by Jos Nuno Oliveira. A concise and deep approach. See also [http://www.di.uminho.pt/~jno/html/ the author's homepage] and also [http://www.di.uminho.pt/~jno/html/jnopub.html his many other papers] -- many materials related to this topic can be found there.<br />
<br />
[[Category:Idioms]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Pointfree&diff=29265
Pointfree
2009-07-27T01:35:32Z
<p>CaleGibbard: (-> a) --> (->) a</p>
<hr />
<div>__TOC__<br />
<br />
'''Pointfree Style'''<br />
<br />
It is very common for functional programmers to write functions as a<br />
composition of other functions, never mentioning the actual arguments<br />
they will be applied to. For example, compare:<br />
<br />
<haskell><br />
sum = foldr (+) 0<br />
</haskell><br />
<br />
with:<br />
<br />
<haskell><br />
sum' xs = foldr (+) 0 xs<br />
</haskell><br />
<br />
These functions perform the same operation, however, the former is more<br />
compact, and is considered cleaner. This is closely related to function<br />
pipelines (and to [http://www.vex.net/~trebla/weblog/pointfree.html unix shell scripting]<br />
): it is clearer to write <hask>let fn = f . g . h</hask> than to<br />
write <hask>let fn x = f (g (h x))</hask>.<br />
<br />
This style is particularly useful when deriving efficient programs by<br />
calculation and, in general, constitutes good discipline. It helps the writer<br />
(and reader) think about composing functions (high level), rather than<br />
shuffling data (low level).<br />
<br />
It is a common experience when rewriting expressions in pointfree style<br />
to derive more compact, clearer versions of the code -- explicit points<br />
often obscure the underlying algorithm.<br />
<br />
Point-free map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr (f . g) e<br />
</haskell><br />
<br />
versus pointful map fusion:<br />
<br />
<haskell><br />
foldr f e . map g == foldr f' e<br />
where f' a b = f (g a) b<br />
</haskell><br />
<br />
Some more examples:<br />
<br />
<haskell><br />
-- point-wise, and point-free member<br />
mem, mem' :: Eq a => a -> [a] -> Bool<br />
<br />
mem x lst = any (== x) lst<br />
mem' = any . (==)<br />
</haskell><br />
<br />
== But pointfree has more points! ==<br />
<br />
A common misconception is that the 'points' of pointfree style are the<br />
<hask>(.)</hask> operator (function composition, as an ASCII symbol),<br />
which uses the same identifier as the decimal point. This is wrong. The<br />
term originated in topology, a branch of mathematics which works with<br />
spaces composed of points, and functions between those spaces. So a<br />
'points-free' definition of a function is one which does not explicitly<br />
mention the points (values) of the space on which the function acts. In<br />
Haskell, our 'space' is some type, and 'points' are values. In the<br />
declaration:<br />
<haskell><br />
f x = x + 1<br />
</haskell><br />
we define the function <hask>f</hask> in terms of its action on an<br />
arbitrary point <hask>x</hask>. Contrast this with the points-free<br />
version:<br />
<haskell><br />
f = (+ 1)<br />
</haskell><br />
where there is no mention of the value on which the function is acting.<br />
<br />
== Background ==<br />
<br />
To find out more about this style, search for Squiggol and the<br />
Bird-Meertens Formalism, a style of functional programming by<br />
calculation that was developed by [http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications.html Richard Bird], [http://www.kestrel.edu/home/people/meertens/ Lambert Meertens], and<br />
others at Oxford University. [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/ Jeremy Gibbons] has also written a number of<br />
papers about the topic, which are cited below.<br />
<br />
== Tool support ==<br />
<br />
Thomas Yaeger has<br />
[http://www.cse.unsw.edu.au/~dons/code/lambdabot/Plugins/Pl/ written] a <br />
[http://www.cse.unsw.edu.au/~dons/lambdabot.html Lambdabot] <br />
plugin to automatically convert a large subset of Haskell expressions to<br />
pointfree form. This tool has made it easier to use the more abstract<br />
pointfree encodings (as it saves some mental gymnastics on the part of<br />
the programmer). You can experiment with this in the [[IRC channel|Haskell IRC channel]]. A stand-alone command-line version is available at [http://hackage.haskell.org/packages/archive/pkg-list.html HackageDB] (package pointfree).<br />
<br />
The @pl (point-less) plugin is rather infamous for using the <hask>(->) a</hask> <br />
[[Monad|monad]] to obtain concise code. It also makes use of [[Arrow|Arrows]]. <br />
It also sometimes produces (amusing) code blow ups with the<br />
<hask>(.)</hask> operator. Recently, @unpl has been written, which<br />
(attempts) to unscramble @pl-ified code.<br />
<br />
A transcript:<br />
<br />
<haskell><br />
> pl \x y -> x y<br />
id<br />
<br />
> unpl id<br />
(\ a -> a)<br />
<br />
> pl \x y -> x + 1<br />
const . (1 +)<br />
<br />
> unpl const . (1 +)<br />
(\ e _ -> 1 + e)<br />
<br />
> pl \v1 v2 -> sum (zipWith (*) v1 v2)<br />
(sum .) . zipWith (*)<br />
<br />
> unpl (sum .) . zipWith (*)<br />
(\ d g -> sum (zipWith (*) d g))<br />
<br />
> pl \x y z -> f (g x y z)<br />
((f .) .) . g<br />
<br />
> unpl ((f .) .) . g<br />
(\ e j m -> f (g e j m))<br />
<br />
> pl \x y z -> f (g x y) z<br />
(f .) . g<br />
<br />
> unpl (f .) . g<br />
(\ d i -> f (g d i))<br />
<br />
> pl \x y z -> f z (g x y)<br />
(flip f .) . g<br />
<br />
> unpl (flip f .) . g<br />
(\ i l c -> f c (g i l))<br />
<br />
> pl \(a,b) -> (b,a)<br />
uncurry (flip (,))<br />
<br />
> pl f a b = b a<br />
f = flip id<br />
<br />
> pl \ x -> x * x<br />
join (*)<br />
<br />
> pl \a b -> a:b:[]<br />
(. return) . (:)<br />
<br />
> pl \x -> x+x+x<br />
(+) =<< join (+)<br />
<br />
> pl \a b -> Nothing<br />
const (const Nothing)<br />
<br />
> pl \(a,b) -> (f a, g b)<br />
f *** g<br />
<br />
> pl \f g h x -> f x `h` g x<br />
flip . (ap .) . flip (.)<br />
<br />
> pl \x y -> x . f . y<br />
(. (f .)) . (.)<br />
<br />
> pl \f xs -> xs >>= return . f<br />
fmap<br />
<br />
> pl \h f g x -> f x `h` g x<br />
liftM2<br />
<br />
> pl \f a b c d -> f b c d a<br />
flip . ((flip . (flip .)) .)<br />
<br />
> pl \a (b,c) -> a c b<br />
(`ap` snd) . (. fst) . flip<br />
<br />
> pl \x y -> compare (f x) (f y)<br />
((. f) . compare .)<br />
</haskell><br />
<br />
For many many more examples, google for the results of '@pl' in the<br />
[[IRC_channel|#haskell]] logs. (Or join #haskell on FreeNode and try it<br />
yourself!) It can, of course, get out of hand:<br />
<br />
<haskell><br />
> pl \(a,b) -> a:b:[]<br />
uncurry ((. return) . (:))<br />
<br />
> pl \a b c -> a*b+2+c<br />
((+) .) . flip flip 2 . ((+) .) . (*)<br />
<br />
> pl \f (a,b) -> (f a, f b)<br />
(`ap` snd) . (. fst) . (flip =<< (((.) . (,)) .))<br />
<br />
> pl \f g (a,b) -> (f a, g b)<br />
flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
<br />
> unpl flip flip snd . (ap .) . flip flip fst . ((.) .) . flip . (((.) . (,)) .)<br />
(\ aa f -><br />
(\ p w -> ((,)) (aa (fst p)) (f w)) >>=<br />
\ ao -> snd >>= \ an -> return (ao an))<br />
</haskell><br />
<br />
== Combinator discoveries ==<br />
<br />
Some fun combinators have been found via @pl. Here we list some of the<br />
best:<br />
<br />
=== The owl ===<br />
<br />
<haskell><br />
((.)$(.))<br />
</haskell><br />
<br />
The owl has type <hask>(a -> b -> c) -> a -> (a1 -> b) -> a1 -><br />
c</hask>, and in pointful style can be written as <hask> f a b c d = a b<br />
(c d)</hask>.<br />
<br />
Example <br />
<haskell><br />
> ((.)$(.)) (==) 1 (1+) 0<br />
True<br />
</haskell><br />
<br />
=== Dot ===<br />
<br />
<haskell><br />
dot = ((.).(.))<br />
<br />
dot :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
sequence `dot` replicate == <br />
(sequence .) . replicate ==<br />
replicateM<br />
<br />
(=<<) == join `dot` fmap<br />
</haskell><br />
<br />
=== Swing ===<br />
<br />
<haskell><br />
swing :: (((a -> b) -> b) -> c -> d) -> c -> a -> d<br />
swing = flip . (. flip id)<br />
swing f c a = f ($ a) c<br />
</haskell><br />
<br />
Some examples of use:<br />
<br />
<haskell><br />
swing map :: forall a b. [a -> b] -> a -> [b]<br />
swing any :: forall a. [a -> Bool] -> a -> Bool<br />
swing foldr :: forall a b. b -> a -> [a -> b -> b] -> b<br />
swing zipWith :: forall a b c. [a -> b -> c] -> a -> [b] -> [c]<br />
swing find :: forall a. [a -> Bool] -> a -> Maybe (a -> Bool)<br />
-- applies each of the predicates to the given value, returning the first predicate which succeeds, if any<br />
swing partition :: forall a. [a -> Bool] -> a -> ([a -> Bool], [a -> Bool])<br />
</haskell><br />
<br />
=== Squish ===<br />
<br />
<haskell><br />
f >>= a . b . c =<< g<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell><br />
(readFile y >>=) . ((a . b) .) . c =<< readFile x<br />
</haskell><br />
<br />
[[/Combine|An actually useful example]], numbering lines of a file.<br />
<br />
== Problems with pointfree ==<br />
<br />
Point-free style can (clearly) lead to [[Obfuscation]] when used unwisely.<br />
As higher-order functions are chained together, it can become harder to<br />
mentally infer the types of expressions. The mental cues to an<br />
expression's type (explicit function arguments, and the number of<br />
arguments) go missing.<br />
<br />
Point-free style often times leads to code which is difficult to modify. A function written in a pointfree style may have to be radically changed to make minor changes in functionality. This is because the function becomes more complicated than a composition of lambdas and other functions, and compositions must be changed to application for a pointful function.<br />
<br />
Perhaps these are why pointfree style is sometimes (often?) referred to as<br />
''pointless style''.<br />
<br />
== References ==<br />
<br />
One early reference is<br />
<br />
* Backus, J. 1978. "Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs," Communications of the Association for Computing Machinery 21:613-641.<br />
<br />
which appears to be available (as a scan) at http://www.stanford.edu/class/cs242/readings/backus.pdf<br />
<br />
A paper specifically about point-free style: <br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#radix<br />
<br />
This style underlies a lot of expert Haskeller's intuitions. <br />
A rather infamous paper (for all the cute symbols) is Erik Meijer et. al's:<br />
<br />
* Functional Programming with Bananas, Lenses, and Barbed Wire, http://wwwhome.cs.utwente.nl/~fokkinga/mmf91m.ps.<br />
<br />
[http://en.wikipedia.org/wiki/Squiggol Squiggol], and the Bird-Meertens Formalism:<br />
* http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#squiggolintro.<br />
* A Calculus of Functions for Program Derivation, R.S. Bird, in Res Topics in Fnl Prog, D. Turner ed, A-W 1990.<br />
* The Squiggolist, ed Johan Jeuring, published irregularly by CWI Amsterdam.<br />
<br />
[http://wiki.di.uminho.pt/twiki/bin/view/Personal/Alcino/PointlessHaskell Pointless Haskell] is a library for point-free programming with recursion patterns defined as hylomorphisms. It also allows the visualization of the intermediate data structure of the hylomorphisms with GHood. This feature together with the DrHylo tool allows us to easily visualize recursion trees of Haskell functions. [http://wiki.di.uminho.pt/wiki/pub/Ze/Bic/report.pdf Haskell Manipulation] by Jose Miguel Paiva Proenca discusses this tool based approach to re-factoring.<br />
<br />
This project is written by [http://www.di.uminho.pt/~mac/ Manuel Alcino Cunha], see his homepage for more related materials on the topic.<br />
An extended verson of his paper ''Point-free Programming with Hylomorphisms'' can be found [http://web.comlab.ox.ac.uk/oucl/research/pdt/ap/dgp/workshop2004/cunha.pdf here].<br />
<br />
== Other areas ==<br />
<br />
[[Combinatory logic]] and also [[Recursive function theory]] can be said in some sense pointfree.<br />
<br />
Are there pointfree approaches to [[relational algebra]]?<br />
See [http://www.di.uminho.pt/~jno/ps/_.pdf First Steps in Pointfree Functional Dependency Theory] written by Jos Nuno Oliveira. A concise and deep approach. See also [http://www.di.uminho.pt/~jno/html/ the author's homepage] and also [http://www.di.uminho.pt/~jno/html/jnopub.html his many other papers] -- many materials related to this topic can be found there.<br />
<br />
[[Category:Idioms]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Cookbook/Files&diff=28229
Cookbook/Files
2009-05-17T00:09:19Z
<p>CaleGibbard: </p>
<hr />
<div>= Reading from a file =<br />
The System.IO library contains the functions needed for file IO. The program<br />
below displays the contents of the file c:\test.txt.<br />
<br />
<haskell><br />
import System.IO<br />
<br />
main = do<br />
h <- openFile "c:\\test.txt" ReadMode<br />
contents <- hGetContents h<br />
putStrLn contents<br />
</haskell><br />
<br />
''Note: It is important never to call ''<code>hClose</code>'' on a file-handle which has had ''<code>hGetContents</code>'' run on it already. The file handle is in a semi-closed state, and will be closed when the resulting string is garbage collected. Closing it manually may result in a random truncation of the input.''<br />
<br />
The same program, with some higher-level functions:<br />
<br />
<haskell><br />
main = do<br />
contents <- readFile "c:\\test.txt"<br />
putStrLn contents<br />
</haskell><br />
<br />
= Writing to a file =<br />
<br />
The following program writes the first 100 squares to a file:<br />
<haskell><br />
-- generate a list of squares with length 'num' in string-format.<br />
numbers num = unlines $ take num $ map (show . \x -> x*x) [1..]<br />
<br />
main = do<br />
writeFile "test.txt" (numbers 100)<br />
putStrLn "successfully written"<br />
</haskell><br />
<br />
This will override the old contents of the file, or create a new file if the file doesn't exist yet. If you want to append to a file, you can use <hask>appendFile</hask>.<br />
<br />
= Creating a temporary file =<br />
<br />
TODO: abstract via 'withTempFile', handle exception<br />
<br />
<haskell><br />
import System.IO<br />
import System.Directory<br />
<br />
main = do<br />
tmpDir <- getTemporaryDirectory<br />
(tmpFile, h) <- openTempFile tmpDir "foo"<br />
hPutStr h "Hello world"<br />
hClose h<br />
removeFile tmpFile<br />
</haskell><br />
<br />
= Writing a filter =<br />
Using [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:interact interact], you can easily do things with stdin and stdout.<br />
<br />
A program to sum up numbers:<br />
<br />
<haskell>main = interact $ show . sum . map read . lines</haskell><br />
<br />
A program that adds line numbers to each line:<br />
<br />
<haskell><br />
main = interact numberLines<br />
numberLines = unlines . zipWith combine [1..] . lines<br />
where combine lineNumber text = concat [show lineNumber, " ", text]<br />
</haskell><br />
<br />
= Logging to a file =<br />
<br />
TODO</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Sudoku&diff=25966
Sudoku
2009-01-20T02:50:32Z
<p>CaleGibbard: </p>
<hr />
<div>[[Category:Code]]<br />
<br />
Here are a few Sudoku solvers coded up in Haskell...<br />
<br />
== Monadic non-deterministic solver ==<br />
<br />
Here is a solver by CaleGibbard. It possibly looks even more naïve than it actually is. This does a backtracking search, trying possibilities until it finds one which works, and backtracking when it can no longer make a legal move.<br />
<br />
<haskell><br />
import MonadNondet (option)<br />
import Sudoku<br />
import System<br />
import Control.Monad<br />
<br />
solve = forM [(i,j) | i <- [1..9], j <- [1..9]] $ \(i,j) -> do<br />
v <- valAt (i,j) -- ^ for each board position<br />
when (v == 0) $ do -- if it's empty (we represent that with a 0)<br />
a <- option [1..9] -- pick a number<br />
place (i,j) a -- and try to put it there<br />
<br />
main = do<br />
[f] <- getArgs<br />
xs <- readFile f<br />
putStrLn . evalSudoku $ do { readSudoku xs; solve; showSudoku }<br />
</haskell><br />
<br />
Now, to the meat of the thing, the monad which makes the above look so nice. We construct a monad which is suitable for maintaining Sudoku grids and trying options nondeterministically. Note that outside of this module, it's impossible to create a state which has an invalid Sudoku grid, since the only way to update the state handles the check to ensure that the move is legal.<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts #-}<br />
module Sudoku <br />
(Sudoku,<br />
readSudoku,<br />
runSudoku,<br />
evalSudoku,<br />
execSudoku,<br />
showSudoku,<br />
valAt, rowAt, colAt, boxAt,<br />
place)<br />
where<br />
import Data.Array.Diff<br />
import MonadNondet<br />
import Control.Monad.State<br />
<br />
-- Nondet here is a drop-in replacement for [] (the list monad) which just runs a little faster.<br />
newtype Sudoku a = Sudoku (StateT (DiffUArray (Int,Int) Int) Nondet a)<br />
deriving (Functor, Monad, MonadPlus)<br />
<br />
{- -- That is, we could also use the following, which works exactly the same way.<br />
newtype Sudoku a = Sudoku (StateT (DiffUArray (Int,Int) Int) [] a)<br />
deriving (Functor, Monad, MonadPlus)<br />
-}<br />
<br />
initialSudokuArray = listArray ((1,1),(9,9)) [0,0..]<br />
<br />
runSudoku (Sudoku k) = runNondet (runStateT k initialSudokuArray)<br />
<br />
evalSudoku = fst . runSudoku<br />
execSudoku = snd . runSudoku<br />
<br />
showSudoku = Sudoku $ do<br />
a <- get<br />
return $ unlines [unwords [show (a ! (i,j)) | j <- [1..9]] | i <- [1..9]]<br />
<br />
readSudoku :: String -> Sudoku ()<br />
readSudoku xs = sequence_ $ do<br />
(i,ys) <- zip [1..9] (lines xs)<br />
(j,n) <- zip [1..9] (words ys)<br />
return $ place (i,j) (read n)<br />
<br />
valAt' (i,j) = do<br />
a <- get<br />
return (a ! (i,j))<br />
<br />
rowAt' (i,j) = mapM valAt' [(i, k) | k <- [1..9]]<br />
<br />
colAt' (i,j) = mapM valAt' [(k, j) | k <- [1..9]] <br />
<br />
boxAt' (i,j) = mapM valAt' [(i' + u, j' + v) | u <- [1..3], v <- [1..3]]<br />
where i' = ((i-1) `div` 3) * 3<br />
j' = ((j-1) `div` 3) * 3<br />
<br />
valAt = Sudoku . valAt'<br />
rowAt = Sudoku . rowAt'<br />
colAt = Sudoku . colAt'<br />
boxAt = Sudoku . boxAt'<br />
<br />
-- This is the least trivial part.<br />
-- It just guards to make sure that the move is legal,<br />
-- and updates the array in the state if it is.<br />
place :: (Int,Int) -> Int -> Sudoku ()<br />
place (i,j) n = Sudoku $ do<br />
v <- valAt' (i,j)<br />
when (v == 0 && n /= 0) $ do<br />
rs <- rowAt' (i,j)<br />
cs <- colAt' (i,j)<br />
bs <- boxAt' (i,j)<br />
guard $ not . any (== n) $ rs ++ cs ++ bs<br />
a <- get<br />
put (a // [((i,j),n)])<br />
</haskell><br />
<br />
This is a fast NonDeterminism monad. It's a drop-in replacement for the list monad in this case. It's twice as fast when compiled with optimisations but a little slower without. You can also find it on the wiki at NonDeterminism.<br />
<br />
I've made a few small modifications to this one to hopefully make it more concretely readable.<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts #-}<br />
<br />
module MonadNondet where<br />
<br />
import Control.Monad<br />
import Control.Monad.Trans<br />
<br />
import Control.Monad.Identity<br />
<br />
newtype NondetT m a<br />
= NondetT { foldNondetT :: (forall b. (a -> m b -> m b) -> m b -> m b) }<br />
<br />
runNondetT :: (Monad m) => NondetT m a -> m a<br />
runNondetT m = foldNondetT m (\x xs -> return x) (error "No solution found.")<br />
<br />
instance (Functor m) => Functor (NondetT m) where<br />
fmap f (NondetT g) = NondetT (\cons nil -> g (cons . f) nil)<br />
<br />
instance (Monad m) => Monad (NondetT m) where<br />
return a = NondetT (\cons nil -> cons a nil)<br />
m >>= k = NondetT (\cons nil -> foldNondetT m (\x -> foldNondetT (k x) cons) nil)<br />
<br />
instance (Monad m) => MonadPlus (NondetT m) where<br />
mzero = NondetT (\cons nil -> nil)<br />
m1 `mplus` m2 = NondetT (\cons -> foldNondetT m1 cons . foldNondetT m2 cons)<br />
<br />
instance MonadTrans NondetT where<br />
lift m = NondetT (\cons nil -> m >>= \a -> cons a nil)<br />
<br />
newtype Nondet a = Nondet (NondetT Identity a) deriving (Functor, Monad, MonadPlus)<br />
runNondet (Nondet x) = runIdentity (runNondetT x)<br />
<br />
foldNondet :: Nondet a -> (a -> b -> b) -> b -> b<br />
foldNondet (Nondet nd) cons nil =<br />
runIdentity $ foldNondetT nd (\x xs -> return (cons x (runIdentity xs))) (return nil)<br />
<br />
option :: (MonadPlus m) => [a] -> m a<br />
option = msum . map return<br />
</haskell><br />
<br />
<br />
<br />
<br />
== Simple solver ==<br />
<br />
By AlsonKemp. This solver is probably similar to Cale's but I don't grok the non-deterministic monad...<br />
<br />
Note: this solver is exhaustive and will output all of the solutions, not just the first one. In order to make it non-exhaustive, add a case statement to solve' in order to check "r" and branch on the result.<br />
<br />
<haskell><br />
import System<br />
import Control.Monad<br />
import Data.List<br />
import Data.Array.IO<br />
<br />
type SodokuBoard = IOArray Int Int<br />
<br />
main = do<br />
[f] <- getArgs<br />
a <- newArray (1, 81) 0<br />
readFile f >>= readSodokuBoard a<br />
putStrLn "Original:"<br />
printSodokuBoard a<br />
putStrLn "Solutions:"<br />
solve a (1,1)<br />
<br />
readSodokuBoard a xs = sequence_ $ do (i,ys) <- zip [1..9] (lines xs)<br />
(j,n) <- zip [1..9] (words ys)<br />
return $ writeBoard a (j,i) (read n)<br />
<br />
printSodokuBoard a =<br />
let printLine a y =<br />
mapM (\x -> readBoard a (x,y)) [1..9] >>= mapM_ (putStr . show) in<br />
putStrLn "-----------" >> <br />
mapM_ (\y -> putStr "|" >> printLine a y >> putStrLn "|") [1..9] >> <br />
putStrLn "-----------"<br />
<br />
-- the meat of the program. Checks the current square.<br />
-- If 0, then get the list of nums and try to "solve' "<br />
-- Otherwise, go to the next square.<br />
solve :: SodokuBoard -> (Int, Int) -> IO (Maybe SodokuBoard)<br />
solve a (10,y) = solve a (1,y+1)<br />
solve a (_, 10)= printSodokuBoard a >> return (Just a)<br />
solve a (x,y) = do v <- readBoard a (x,y)<br />
case v of<br />
0 -> availableNums a (x,y) >>= solve' a (x,y)<br />
_ -> solve a (x+1,y)<br />
-- solve' handles the backtacking<br />
where solve' a (x,y) [] = return Nothing<br />
solve' a (x,y) (v:vs) = do writeBoard a (x,y) v -- put a guess onto the board<br />
r <- solve a (x+1,y)<br />
writeBoard a (x,y) 0 -- remove the guess from the board<br />
solve' a (x,y) vs -- recurse over the remainder of the list<br />
<br />
-- get the "taken" numbers from a row, col or box.<br />
getRowNums a y = sequence [readBoard a (x',y) | x' <- [1..9]]<br />
getColNums a x = sequence [readBoard a (x,y') | y' <- [1..9]]<br />
getBoxNums a (x,y) = sequence [readBoard a (x'+u, y'+v) | u <- [0..2], v <- [0..2]] <br />
where x' = (3 * ((x-1) `quot` 3)) + 1<br />
y' = (3 * ((y-1) `quot` 3)) + 1<br />
<br />
-- return the numbers that are available for a particular square<br />
availableNums a (x,y) = do r <- getRowNums a y <br />
c <- getColNums a x<br />
b <- getBoxNums a (x,y)<br />
return $ [0..9] \\ (r `union` c `union` b) <br />
<br />
-- aliases of read and write array that flatten the index<br />
readBoard a (x,y) = readArray a (x+9*(y-1))<br />
writeBoard a (x,y) e = writeArray a (x+9*(y-1)) e<br />
</haskell><br />
<br />
== Complete decision tree ==<br />
<br />
By Henning Thielemann.<br />
<br />
<haskell><br />
module Sudoku where<br />
<br />
{-<br />
This is inspired by John Hughes "Why Functional Programming Matters".<br />
We build a complete decision tree.<br />
That is, all alternatives in a certain depth<br />
have the same number of determined values.<br />
At the bottom of the tree all possible solutions can be found.<br />
Actually the algorithm is very stupid:<br />
In each depth we look for the field with the least admissible choices of numbers<br />
and prune the alternative branches for the other fields.<br />
-}<br />
<br />
import Data.Char (ord, chr)<br />
import Data.Array (Array, range, (!), (//))<br />
import Data.Tree (Tree)<br />
import qualified Data.Tree as Tree<br />
import Data.List (sort, minimumBy)<br />
import Data.Maybe (catMaybes, isNothing, fromMaybe, fromJust)<br />
import qualified Data.Array as Array<br />
<br />
{-<br />
Example:<br />
<br />
ghci -Wall Sudoku.hs<br />
<br />
*Sudoku> mapM putCLn (solutions exampleHawiki0)<br />
-}<br />
<br />
<br />
{- [[ATree]] contains a list of possible alternatives for each position -}<br />
data ATree a = ANode T [[ATree a]]<br />
<br />
type Coord = Int<br />
type Address = (Int,Int,Int,Int)<br />
type Element = Int<br />
<br />
type T = Array Address (Maybe Element)<br />
type Complete = Array Address Element<br />
<br />
fieldBounds :: (Address, Address)<br />
fieldBounds = ((0,0,0,0), (2,2,2,2))<br />
<br />
squareRange :: [(Coord, Coord)]<br />
squareRange = range ((0,0), (2,2))<br />
<br />
alphabet :: [Element]<br />
alphabet = [1..9]<br />
<br />
<br />
<br />
{- * solution -}<br />
<br />
{-<br />
Given two sorted lists,<br />
remove the elements of the first list from the second one.<br />
-}<br />
deleteSorted :: Ord a => [a] -> [a] -> [a]<br />
deleteSorted [] ys = ys<br />
deleteSorted _ [] = []<br />
deleteSorted (x:xs) (y:ys) =<br />
case compare x y of<br />
EQ -> deleteSorted xs ys<br />
LT -> deleteSorted xs (y:ys)<br />
GT -> y : deleteSorted (x:xs) ys<br />
<br />
admissibleNumbers :: [[Maybe Element]] -> [Element]<br />
admissibleNumbers =<br />
foldl (flip deleteSorted) alphabet .<br />
map (sort . catMaybes)<br />
<br />
admissibleAdditions :: T -> Address -> [Element]<br />
admissibleAdditions sudoku (i,j,k,l) =<br />
admissibleNumbers (map ($ sudoku)<br />
[selectRow (i,k),<br />
selectColumn (j,l),<br />
selectSquare (i,j)])<br />
<br />
allAdmissibleAdditions :: T -> [(Address, [Element])]<br />
allAdmissibleAdditions sudoku =<br />
let adds addr =<br />
(addr, admissibleAdditions sudoku addr)<br />
in map adds<br />
(map fst (filter (isNothing . snd)<br />
(Array.assocs sudoku)))<br />
<br />
<br />
<br />
solutionTree :: T -> ATree T<br />
solutionTree sudoku =<br />
let new (addr,elms) =<br />
map (\elm -> solutionTree (sudoku // [(addr, Just elm)])) elms<br />
in ANode sudoku (map new (allAdmissibleAdditions sudoku))<br />
<br />
treeAltToStandard :: ATree T -> Tree T<br />
treeAltToStandard (ANode sudoku subs) =<br />
Tree.Node sudoku (concatMap (map treeAltToStandard) subs)<br />
<br />
{- Convert a tree with alternatives for each position (ATree)<br />
into a normal tree by choosing one position and its alternative values.<br />
We need to consider only one position per level<br />
because the remaining positions are processed in the sub-levels.<br />
With other words: Choosing more than one position<br />
would lead to multiple reports of the same solution.<br />
<br />
For reasons of efficiency<br />
we choose the position with the least number of alternatives.<br />
If this number is zero, the numbers tried so far are wrong.<br />
If this number is one, then the choice is unique, but maybe still wrong.<br />
If the number of alternatives is larger,<br />
we have to check each alternative.<br />
-}<br />
treeAltToStandardOptimize :: ATree T -> Tree T<br />
treeAltToStandardOptimize (ANode sudoku subs) =<br />
let chooseMinLen [] = []<br />
chooseMinLen xs = minimumBy compareLength xs<br />
in Tree.Node sudoku (chooseMinLen<br />
(map (map treeAltToStandardOptimize) subs))<br />
<br />
maybeComplete :: T -> Maybe Complete<br />
maybeComplete sudoku =<br />
fmap (Array.array fieldBounds)<br />
(mapM (uncurry (fmap . (,))) (Array.assocs sudoku))<br />
<br />
{- All leafs are at the same depth,<br />
namely the number of undetermined fields.<br />
That's why we can safely select all Sudokus at the lowest level. -}<br />
solutions :: T -> [Complete]<br />
solutions sudoku =<br />
let err = error "The lowest level should contain complete Sudokus only."<br />
{- "last'" is more efficient than "last" here<br />
because the program does not have to check<br />
whether deeper levels exist.<br />
We know that the tree is as deep<br />
as the number of undefined fields.<br />
This means that dropMatch returns a singleton list.<br />
We don't check that<br />
because then we would lose the efficiency again. -}<br />
last' = head . dropMatch (filter isNothing (Array.elems sudoku))<br />
in map (fromMaybe err . maybeComplete)<br />
(last' (Tree.levels<br />
(treeAltToStandardOptimize (solutionTree sudoku))))<br />
<br />
<br />
<br />
{- * transformations (can be used for construction, too) -}<br />
<br />
standard :: Complete<br />
standard =<br />
Array.listArray fieldBounds<br />
(map (\(i,j,k,l) -> mod (j+k) 3 * 3 + mod (i+l) 3 + 1)<br />
(range fieldBounds))<br />
<br />
<br />
exampleHawiki0, exampleHawiki1 :: T<br />
exampleHawiki0 = fromString (unlines [<br />
" 5 6 1",<br />
" 48 7 ",<br />
"8 52",<br />
"2 57 3 ",<br />
" ",<br />
" 3 69 5",<br />
"79 8",<br />
" 1 65 ",<br />
"5 3 6 "<br />
])<br />
<br />
exampleHawiki1 = fromString (unlines [<br />
" 6 8 ",<br />
" 2 ",<br />
" 1 ",<br />
" 7 1 2",<br />
"5 3 ",<br />
" 4 ",<br />
" 42 1 ",<br />
"3 7 6 ",<br />
" 5 "<br />
])<br />
<br />
<br />
<br />
<br />
check :: Complete -> Bool<br />
check sudoku =<br />
let checkParts select =<br />
all (\addr -> sort (select addr sudoku) == alphabet) squareRange<br />
in all checkParts [selectRow, selectColumn, selectSquare]<br />
<br />
selectRow, selectColumn, selectSquare ::<br />
(Coord,Coord) -> Array Address element -> [element]<br />
selectRow (i,k) sudoku =<br />
map (sudoku!) (range ((i,0,k,0), (i,2,k,2)))<br />
-- map (sudoku!) (map (\(j,l) -> (i,j,k,l)) squareRange)<br />
selectColumn (j,l) sudoku =<br />
map (sudoku!) (range ((0,j,0,l), (2,j,2,l)))<br />
selectSquare (i,j) sudoku =<br />
map (sudoku!) (range ((i,j,0,0), (i,j,2,2)))<br />
<br />
<br />
{- * conversion from and to strings -}<br />
<br />
put, putLn :: T -> IO ()<br />
put sudoku = putStr (toString sudoku)<br />
putLn sudoku = putStrLn (toString sudoku)<br />
<br />
putC, putCLn :: Complete -> IO ()<br />
putC sudoku = putStr (toString (fmap Just sudoku))<br />
putCLn sudoku = putStrLn (toString (fmap Just sudoku))<br />
<br />
fromString :: String -> T<br />
fromString str =<br />
Array.array fieldBounds (concat<br />
(zipWith (\(i,k) -> map (\((j,l),x) -> ((i,j,k,l),x)))<br />
squareRange<br />
(map (zip squareRange . map charToElem) (lines str))))<br />
<br />
toString :: T -> String<br />
toString sudoku =<br />
unlines<br />
(map (\(i,k) -> map (\(j,l) -> elemToChar (sudoku!(i,j,k,l)))<br />
squareRange)<br />
squareRange)<br />
<br />
charToElem :: Char -> Maybe Element<br />
charToElem c =<br />
toMaybe ('0'<=c && c<='9') (ord c - ord '0')<br />
<br />
elemToChar :: Maybe Element -> Char<br />
elemToChar =<br />
maybe ' ' (\c -> chr (ord '0' + c))<br />
<br />
<br />
{- * helper functions -}<br />
<br />
nest :: Int -> (a -> a) -> a -> a<br />
nest 0 _ x = x<br />
nest n f x = f (nest (n-1) f x)<br />
<br />
toMaybe :: Bool -> a -> Maybe a<br />
toMaybe False _ = Nothing<br />
toMaybe True x = Just x<br />
<br />
compareLength :: [a] -> [b] -> Ordering<br />
compareLength (_:xs) (_:ys) = compareLength xs ys<br />
compareLength [] [] = EQ<br />
compareLength (_:_) [] = GT<br />
compareLength [] (_:_) = LT<br />
<br />
{- | Drop as many elements as the first list is long -}<br />
dropMatch :: [b] -> [a] -> [a]<br />
dropMatch xs ys =<br />
map fromJust (dropWhile isNothing<br />
(zipWith (toMaybe . null) (iterate (drop 1) xs) ys))<br />
</haskell><br />
<br />
<br />
== No guessing ==<br />
<br />
By Simon Peyton Jones.<br />
<br />
Since this page is here I thought I'd add a solver I wrote sometime last year. The main constraint I imposed is that it never guesses, and that it outputs a human-comprehensible explanation of every step of its reasoning. That means there are some puzzles it can't solve. I'd be interested to know if there are any puzzles that it gets stuck on where there is a no-guessing way forward. I made no attempt to make it fast.<br />
<br />
There are two files: [[Media:SudokuPJ.hs]] and [[Media:TestPJ.hs]]. The latter just contains a bunch of test cases; I was too lazy to write a proper parser.<br />
<br />
The main entry point is:<br />
<pre><br />
run1 :: Verbosity -> [String] -> Doc<br />
data Verbosity = All | Terse | Final<br />
</pre><br />
The <tt>[String]</tt> the starting board configuration (see the tests file).<br />
<br />
== Just guessing ==<br />
<br />
By ChrisKuklewicz<br />
<br />
This solver is an implementation of Knuth's "Dancing Links" algorithm for solving binary-cover problems. This algorithm represents the constraints as a sparse binary matrix, with 1's as linked nodes. The nodes are in a vertical and a horizontal doubly linked list, and each vertical list is headed by another node that represents one of the constraints. It is interesting as an example of the rare beast in Haskell: a mutable data structure. The code has been rewritten and cleaned up here [[Media:DancingSudoku.lhs]]. Its main routine is designed to handle the input from [http://www.csse.uwa.edu.au/~gordon/sudoku17 sudoku17] on stdin. Currently it only returns the first solution or calls an error, it can be modified (see comments in the file) to return all solutions in a list. An earlier version used ST.Lazy instead of ST.Strict which made operating on puzzles with many solutions more tractable.<br />
<br />
Other trivia: It uses "mdo" and lazyness to initialize some of the doubly linked lists.<br />
<br />
== Very smart, with only a little guessing ==<br />
<br />
by ChrisKuklewicz<br />
<br />
This solver does its best to avoid the branch and guess approach. On the 36628 puzzles of [http://www.csse.uwa.edu.au/~gordon/sudokumin.php length 17] it resorts to guessing on only 164. This extra strength comes from examining the constraints that can only be solved in exactly two ways, and how these constraints overlap and interact with each other and remaining possibilities.<br />
<br />
The [http://evenmere.org/~chrisk/chris-sudoku-deduce.tar.gz source code] compiles to take a list of puzzles as input and produces a description of the number of (good and total) guesses required, as well as a shuffled version of the input. If there was guessing, then the shuffled version could be sent back into the solver to see how the difficulty depended on luck. The list of 164 hard puzzles is included with the source code. The Deduce.hs file contains comments.<br />
<br />
The data is stored in a 9x9x9 boolean array, and the only operations are turning off possibilities and branching. For performance the array is thawed, mutated, and frozen. On the set of 36628 puzzles the speed averages 9.4 puzzles solved per second on a 1.33 GHz G4 (ghc-6.4.1 on OS X). I liked the 9x9x9 array since it emphasized the symmetry of the problem.<br />
<br />
== Only guessing without dancing links ==<br />
<br />
by AndrewBromage<br />
<br />
[http://andrew.bromage.org/darcs/sudoku/ This solver] uses a different implementation of Knuth's algorithm, without using pointers. It instead relies on the fact that in Haskell, tree-like data structure (in this case, a [[Priority Search Queue]]) "undo" operations are essentially free.<br />
<br />
== Generalized solver ==<br />
<br />
By Thorkil Naur<br />
<br />
This Su Doku solver is able to solve classes of Su Doku puzzles that extend the ordinary 9*9 puzzles. The [[SuDokuThorkilNaurDocument|documentation]] describes the solver and also some (to the present author at least) surprising properties of various reduction strategies used when solving Su Doku puzzles.<br />
<br />
The following files comprise the Su Doku solver and related code:<br />
<br />
[[Media:Format.hs]]<br />
[[Media:Merge.hs]]<br />
[[Media:SdkMSol2.hs]]<br />
[[Media:SortByF.hs]]<br />
[[Media:SuDoku.hs]]<br />
[[Media:t40.hs]]<br />
[[Media:t44.hs]]<br />
[[Media:Test.hs]]<br />
<br />
For an example of use, the command<br />
<br />
<pre><br />
runhugs SdkMSol2 \<br />
tn1 \<br />
Traditional 3 \<br />
-#123456789 \<br />
1-53---9- \<br />
---6----- \<br />
------271 \<br />
82------- \<br />
---487--- \<br />
------53- \<br />
23------- \<br />
--7-59--- \<br />
--6---8-4<br />
</pre><br />
<br />
produces output that, among other things, contain<br />
<br />
<pre><br />
tn1: Solutions:<br />
1 7 5 3 2 8 4 9 6<br />
9 4 2 6 7 1 3 8 5<br />
3 6 8 5 9 4 2 7 1<br />
8 2 9 1 3 5 6 4 7<br />
6 5 3 4 8 7 9 1 2<br />
7 1 4 9 6 2 5 3 8<br />
2 3 1 8 4 6 7 5 9<br />
4 8 7 2 5 9 1 6 3<br />
5 9 6 7 1 3 8 2 4<br />
</pre><br />
<br />
== Simple small solver ==<br />
I haven't looked at the other solvers in detail yet, so I'm not sure what is good or bad about mine, but here it is:<br />
<br />
http://darcs.brianweb.net/sudoku/Sudoku.pdf<br />
http://darcs.brianweb.net/sudoku/src/Sudoku.lhs<br />
<br />
-Brian Alliet <brian@brianweb.net><br />
<br />
== Backtrack monad solver ==<br />
<br />
This is a simple but fast solver that uses standard<br />
monads from the [[MonadTemplateLibrary]] in the [[StandardLibraries]].<br />
<br />
Besides being Yet Another Example of a Sudoko solver,<br />
I think it is also a nice somewhat-nontrivial example of<br />
monads in practice.<br />
<br />
The idea is that the monad StateT s [] does backtracking.<br />
It means "iterate over a list while keeping state,<br />
but re-initialize to the original state on each iteration".<br />
<br />
I have several (Unix command line) front-ends to this<br />
module, available upon request. The one I use most creates<br />
and prints six new Sudoku puzzles on a page, with<br />
fine-grain control over the difficulty of the puzzle.<br />
This has made me quite popular among friends and<br />
extended family.<br />
<br />
- [[YitzGale]]<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts #-}<br />
<br />
-- Solve a Sudoku puzzle<br />
<br />
module Sudoku where<br />
<br />
import Control.Monad.State<br />
import Data.Maybe (maybeToList)<br />
import Data.List (delete)<br />
<br />
type Value = Int<br />
type Cell = (Int, Int) -- One-based coordinates<br />
<br />
type Puzzle = [[Maybe Value]]<br />
type Solution = [[Value]]<br />
<br />
-- The size of the puzzle.<br />
sqrtSize :: Int<br />
sqrtSize = 3<br />
size = sqrtSize * sqrtSize<br />
<br />
-- Besides the rows and columns, a Sudoku puzzle contains s blocks<br />
-- of s cells each, where s = size.<br />
blocks :: [[Cell]]<br />
blocks = [[(x + i, y + j) | i <- [1..sqrtSize], j <- [1..sqrtSize]] |<br />
x <- [0,sqrtSize..size-sqrtSize],<br />
y <- [0,sqrtSize..size-sqrtSize]]<br />
<br />
-- The one-based number of the block that a cell is contained in.<br />
blockNum :: Cell -> Int<br />
blockNum (row, col) = row - (row - 1) `mod` sqrtSize + (col - 1) `div` sqrtSize<br />
<br />
-- When a Sudoku puzzle has been partially filled in, the following<br />
-- data structure represents the remaining options for how to proceed.<br />
data Options = Options {<br />
cellOpts :: [[[Value]]], -- For each cell, a list of possible values<br />
rowOpts :: [[[Cell ]]], -- For each row and value, a list of cells<br />
colOpts :: [[[Cell ]]], -- For each column and value, a list of cells<br />
blkOpts :: [[[Cell ]]] -- For each block and value, a list of cells<br />
} deriving Show<br />
modifyCellOpts f = do {opts <- get; put $ opts {cellOpts = f $ cellOpts opts}}<br />
modifyRowOpts f = do {opts <- get; put $ opts {rowOpts = f $ rowOpts opts}}<br />
modifyColOpts f = do {opts <- get; put $ opts {colOpts = f $ colOpts opts}}<br />
modifyBlkOpts f = do {opts <- get; put $ opts {blkOpts = f $ blkOpts opts}}<br />
<br />
-- The full set of initial options, before any cells are constrained<br />
initOptions :: Options<br />
initOptions = Options {<br />
cellOpts = [[[1..size] | _ <- [1..size]] | _ <- [1..size]],<br />
rowOpts = [[[(r, c) | c <- [1..size]] | _ <- [1..size]] | r <- [1..size]],<br />
colOpts = [[[(r, c) | r <- [1..size]] | _ <- [1..size]] | c <- [1..size]],<br />
blkOpts = [[b | _ <- [1..size]] | b <- blocks]}<br />
<br />
solve :: Puzzle -> [Solution]<br />
solve puz = evalStateT (initPuzzle >> solutions) initOptions<br />
where<br />
initPuzzle =<br />
sequence_ [fixCell v (r, c) | (row, r) <- zip puz [1..],<br />
(val, c) <- zip row [1..],<br />
v <- maybeToList val]<br />
<br />
-- Build a list of all possible solutions given the current options.<br />
-- We use a list monad INSIDE a state monad. That way,<br />
-- the state is re-initialized on each element of the list iteration,<br />
-- allowing backtracking when an attempt fails (with mzero).<br />
solutions :: StateT Options [] Solution<br />
solutions = solveFromRow 1<br />
where<br />
solveFromRow r<br />
| r > size = return []<br />
| otherwise = do<br />
row <- solveRowFromCol r 1<br />
rows <- solveFromRow $ r + 1<br />
return $ row : rows<br />
solveRowFromCol r c<br />
| c > size = return []<br />
| otherwise = do<br />
vals <- gets $ (!! (c - 1)) . (!! (r - 1)) . cellOpts<br />
val <- lift vals<br />
fixCell val (r, c)<br />
row <- solveRowFromCol r (c + 1)<br />
return $ val : row<br />
<br />
-- Fix the value of a cell.<br />
-- More specifically - update Options to reflect the given value at<br />
-- the given cell, or mzero if that is not possible.<br />
fixCell :: (MonadState Options m, MonadPlus m) =><br />
Value -> Cell -> m ()<br />
fixCell val cell@(row, col) = do<br />
vals <- gets $ (!! (col - 1)) . (!! (row - 1)) . cellOpts<br />
guard $ val `elem` vals<br />
modifyCellOpts $ replace2 row col [val]<br />
modifyRowOpts $ replace2 row val [cell]<br />
modifyColOpts $ replace2 col val [cell]<br />
modifyBlkOpts $ replace2 blk val [cell]<br />
sequence_ [constrainCell v cell | v <- [1..size], v /= val]<br />
sequence_ [constrainCell val (row, c) | c <- [1..size], c /= col]<br />
sequence_ [constrainCell val (r, col) | r <- [1..size], r /= row]<br />
sequence_ [constrainCell val c | c <- blocks !! (blk - 1), c /= cell]<br />
where<br />
blk = blockNum cell<br />
<br />
-- Assert that the given value cannot occur in the given cell.<br />
-- Fail with mzero if that means that there are no options left.<br />
constrainCell :: (MonadState Options m, MonadPlus m) =><br />
Value -> Cell -> m ()<br />
constrainCell val cell@(row, col) = do<br />
constrainOpts row col val cellOpts modifyCellOpts (flip fixCell cell)<br />
constrainOpts row val cell rowOpts modifyRowOpts (fixCell val)<br />
constrainOpts col val cell colOpts modifyColOpts (fixCell val)<br />
constrainOpts blk val cell blkOpts modifyBlkOpts (fixCell val)<br />
where<br />
blk = blockNum cell<br />
constrainOpts x y z getOpts modifyOpts fixOpts = do<br />
zs <- gets $ (!! (y - 1)) . (!! (x - 1)) . getOpts<br />
case zs of<br />
[z'] -> guard (z' /= z)<br />
[_,_] -> when (z `elem` zs) $ fixOpts (head $ delete z zs)<br />
(_:_) -> modifyOpts $ replace2 x y (delete z zs)<br />
_ -> mzero<br />
<br />
-- Replace one element of a list.<br />
-- Coordinates are 1-based.<br />
replace :: Int -> a -> [a] -> [a]<br />
replace i x (y:ys)<br />
| i > 1 = y : replace (i - 1) x ys<br />
| otherwise = x : ys<br />
replace _ _ _ = []<br />
<br />
-- Replace one element of a 2-dimensional list.<br />
-- Coordinates are 1-based.<br />
replace2 :: Int -> Int -> a -> [[a]] -> [[a]]<br />
replace2 i j x (y:ys)<br />
| i > 1 = y : replace2 (i - 1) j x ys<br />
| otherwise = replace j x y : ys<br />
replace2 _ _ _ _ = []<br />
</haskell><br />
<br />
== In-flight entertainment ==<br />
<br />
By Lennart Augustsson<br />
<br />
When on a Lufthansa trans-atlantic flight in 2005 I picked up the in-flight magazine and found a Sudoku puzzle. I decided to finally try one. After solving half of it by hand I got bored. Surely, this mechanical task is better performed by a machine? So I pulled out my laptop and wrote a Haskell program.<br />
<br />
The program below is what I wrote on the plane, except for some comments that I've added. I have made no attempt as making it fast, so the nefarious test puzzle below takes a minute to solve.<br />
<br />
First, the solver without user interface:<br />
<haskell><br />
module Sudoku(Square, Board, ColDigit, RowDigit, BoxDigit, Digit, initialBoard, getBoard, mkSquare, setSquare, solveMany) where<br />
import Char(intToDigit, digitToInt)<br />
import List ((\\), sortBy)<br />
<br />
-- A board is just a list of Squares. It always has all the squares.<br />
data Board = Board [Square]<br />
deriving (Show)<br />
<br />
-- A Square contains its column (ColDigit), row (RowDigit), and<br />
-- which 3x3 box it belongs to (BoxDigit). The box can be computed<br />
-- from the row and column, but is kept for speed.<br />
-- A Square also contains it's status: either a list of possible<br />
-- digits that can be placed in the square OR a fixed digit (i.e.,<br />
-- the square was given by a clue or has been solved).<br />
data Square = Square ColDigit RowDigit BoxDigit (Either [Digit] Digit)<br />
deriving (Show)<br />
<br />
type ColDigit = Digit<br />
type RowDigit = Digit<br />
type BoxDigit = Digit<br />
type Digit = Char -- '1' .. '9'<br />
<br />
-- The initial board, no clues given so all digits are possible in all squares.<br />
initialBoard :: Board<br />
initialBoard = Board [ Square col row (boxDigit col row) (Left allDigits) |<br />
row <- allDigits, col <- allDigits ]<br />
<br />
-- Return a list of rows of a solved board.<br />
-- If used on an unsolved board the return value is unspecified.<br />
getBoard :: Board -> [[Char]]<br />
getBoard (Board sqs) = [ [ getDigit d | Square _ row' _ d <- sqs, row' == row ] | row <- allDigits ]<br />
where getDigit (Right d) = d<br />
getDigit _ = '0'<br />
<br />
allDigits :: [Char]<br />
allDigits = ['1' .. '9']<br />
<br />
-- Compute the box from a column and row.<br />
boxDigit :: ColDigit -> RowDigit -> BoxDigit<br />
boxDigit c r = intToDigit $ (digitToInt c - 1) `div` 3 + (digitToInt r - 1) `div` 3 * 3 + 1<br />
<br />
-- Given a column, row, and a digit make a (solved) square representing this.<br />
mkSquare :: ColDigit -> RowDigit -> Digit -> Square<br />
mkSquare col row c | col `elem` allDigits && row `elem` allDigits && c `elem` allDigits <br />
= Square col row (boxDigit col row) (Right c)<br />
mkSquare _ _ _ = error "Bad mkSquare"<br />
<br />
-- Place a given Square on a Board and return the new Board.<br />
-- Illegal setSquare calls will just error out. The main work here<br />
-- is to remove the placed digit from the other Squares on the board<br />
-- that are in the same column, row, or box.<br />
setSquare :: Square -> Board -> Board<br />
setSquare sq@(Square scol srow sbox (Right d)) (Board sqs) = Board (map set sqs)<br />
where set osq@(Square col row box ds) =<br />
if col == scol && row == srow then sq<br />
else if col == scol || row == srow || box == sbox then (Square col row box (sub ds))<br />
else osq<br />
sub (Left ds) = Left (ds \\ [d])<br />
sub (Right d') | d == d' = error "Impossible setSquare"<br />
sub dd = dd<br />
setSquare _ _ = error "Bad setSquare"<br />
<br />
-- Get the unsolved Squares from a Board.<br />
getLeftSquares :: Board -> [Square]<br />
getLeftSquares (Board sqs) = [ sq | sq@(Square _ _ _ (Left _)) <- sqs ]<br />
<br />
-- Given an initial Board return all the possible solutions starting<br />
-- from that Board.<br />
-- Note, this all happens in the list monad and makes use of lazy evaluation<br />
-- to avoid work. Using the list monad automatically handles all the backtracking<br />
-- and enumeration of solutions.<br />
solveMany :: Board -> [Board]<br />
solveMany brd =<br />
case getLeftSquares brd of<br />
[] -> return brd -- Nothing unsolved remains, we are done.<br />
sqs -> do<br />
-- Sort the unsolved Squares by the ascending length of the possible<br />
-- digits. Pick the first of those so we always solve forced Squares<br />
-- first.<br />
let Square c r b (Left ds) : _ = sortBy leftLen sqs<br />
leftLen (Square _ _ _ (Left ds1)) (Square _ _ _ (Left ds2)) = compare (length ds1) (length ds2)<br />
leftLen _ _ = error "bad leftLen"<br />
sq <- [ Square c r b (Right d) | d <- ds ] -- Try all possible moves<br />
solveMany (setSquare sq brd) -- And solve the extended Board.<br />
</haskell><br />
<br />
Second, a simple user interface (a different user interface that I have is an Excell addin):<br />
<haskell><br />
module Main where<br />
import Sudoku<br />
<br />
-- Col Row Digit<br />
solve :: [((Char, Char), Char)] -> [[Char]]<br />
solve crds =<br />
let brd = foldr add initialBoard crds<br />
add ((c, r), d) = setSquare (mkSquare c r d)<br />
in case solveMany brd of<br />
[] -> error "No solutions"<br />
b : _ -> getBoard b<br />
<br />
-- The parse assumes that squares without a clue<br />
-- contain '0'.<br />
main = interact $<br />
unlines . -- turn it into lines<br />
map (concatMap (:" ")) . -- add a space after each digit for readability<br />
solve . -- solve the puzzle<br />
filter ((`elem` ['1'..'9']) . snd) . -- get rid of non-clues<br />
zip [ (c, r) | r <- ['1'..'9'], c <- ['1'..'9'] ] . -- pair up the digits with their coordinates<br />
filter (`elem` ['0'..'9']) -- get rid of non-digits<br />
</haskell><br />
<br />
<br />
== Sudoku incrementally, Ã la Bird ==<br />
<br />
:As part of a new [http://cs.nott.ac.uk/~gmh/afp.html Advanced Functional Programming] course in Nottingham, [http://cs.nott.ac.uk/~gmh/ Graham Hutton] presented a Haskell approach to solving Sudoku puzzles, based upon notes from [http://web.comlab.ox.ac.uk/oucl/work/richard.bird/ Richard Bird]. The approach is classic Bird: start with a simple but impractical solver, whose efficiency is then improved in a series of steps. The end result is an elegant program that is able to solve any Sudoku puzzle in an instant. Its also an excellent example of what has been termed wholemeal programming focusing on entire data structures rather than their elements. (Transplanted from [http://lambda-the-ultimate.org/node/772 LtU].)<br />
<br />
A full talk-through of the evolution of the code may be found [http://cs.nott.ac.uk/~gmh/sudoku.lhs under the course page]. --[[User:Liyang|Liyang]] 13:35, 27 July 2006 (UTC)<br />
<br />
I've also written [[Media:sudokuWss.hs]], a parallel version of this solver. It uses STM to prune the boxes, columns, and rows simultaneously, which is kind of cool. I'm pretty sure it can be optimized quite a bit... --WouterSwierstra, August 2007.<br />
<br />
== 607 bytes / 12 lines ==<br />
<br />
A super quick attempt at a smallest solution, based on the<br />
[http://web.math.unifi.it/users/maggesi/haskell_sudoku_solver.html 707 byte sudoku] solver:<br />
<br />
<haskell><br />
import List<br />
<br />
main = putStr . unlines . map disp . solve . return . input =<< getContents<br />
<br />
solve s = foldr (\p l -> [mark (p,n) s | s <- l, n <- s p]) s idx<br />
<br />
mark (p@(i,j),n) s q@(x,y)<br />
| p == q = [n]<br />
| x == i || y == j || e x i && e y j = delete n (s q)<br />
| otherwise = s q<br />
where e a b = div (a-1) 3 == div (b-1) 3<br />
<br />
disp s = unlines [unwords [show $ head $ s (i,j) | j <- [1..9]] | i <- [1..9]]<br />
<br />
input s = foldr mark (const [1..9]) $<br />
[(p,n) | (p,n) <- zip idx $ map read $ lines s >>= words, n>0]<br />
<br />
idx = [(i,j) | i <- [1..9], j <- [1..9]]<br />
</haskell><br />
<br />
dons 07:54, 2 December 2006 (UTC)<br />
<br />
== A parallel solver ==<br />
<br />
A parallel version of Richard Bird's function pearl solver by Wouter<br />
Swierstra:<br />
<br />
http://www.haskell.org/sitewiki/images/1/12/SudokuWss.hs<br />
<br />
== Another simple solver ==<br />
<br />
One day I wrote a completely naive sudoku solver which tried all possibilities to try arrays in Haskell. It works, however I doubt that I'll see it actually solve a puzzle during my remaining lifetime.<br />
<br />
So I set out to improve it. The new version still tries all possibilities, but it starts with the cell that has a minimal number of possibilities.<br />
<br />
<haskell><br />
import Array<br />
import List<br />
import System<br />
<br />
-- ([Possible Entries], #Possible Entries)<br />
type Field = Array (Int,Int) ([Int], Int)<br />
<br />
-- Fields are Strings of Numbers with 0 in empty cells<br />
readField ::String -> Field<br />
readField f = listArray ((1,1),(9,9)) (map (\j -> let n=read [j]::Int in if n==0 then ([0..9],9) else ([n],0)) f)<br />
<br />
-- x y wrong way -> reading wrong? no effect on solution though<br />
showField :: Field -> String<br />
showField f = unlines [concat [show $ entry (f!(y,x))|x<-[1..9]]|y<-[1..9]]<br />
<br />
printField :: Maybe Field -> String<br />
printField (Just f) = concat [concat [show $ entry f!(y,x))|x<-[1..9]]|y<-[1..9]]<br />
printField Nothing = "No solution"<br />
<br />
-- true if cell is empty<br />
isEmpty :: ([Int],Int) -> Bool<br />
isEmpty (xs,_) = xs == [0]<br />
<br />
entry :: ([Int],Int) -> Int<br />
entry = head.fst<br />
<br />
-- 0 possibilties left, no emtpy fields<br />
done :: Field -> Bool<br />
done a = let l=elems a in 0==foldr (\(_,x) y -> x+y) 0 l && all (not.isEmpty) l<br />
<br />
--return column/row/square containing coords (x,y), excluding (x,y)<br />
column::Field ->(Int,Int) -> [Int]<br />
column a ~(x,y)= [entry $ a!(i,y)|i<-[1..9],i/=x]<br />
<br />
row :: Field -> (Int,Int) -> [Int]<br />
row a ~(x,y)= [entry $ a!(x,j)|j<-[1..9],j/=y]<br />
<br />
square :: Field -> (Int, Int)-> [Int]<br />
square a ~(x,y) = block <br />
where <br />
n = head $ dropWhile (<x-3) [0,3,6]<br />
m = head $ dropWhile (<y-3) [0,3,6]<br />
block = [entry $ a!(i+n,j+m)|i<-[1..3],j<-[1..3],x/=i+n || y/=j+m]<br />
<br />
-- remove invalid possibilities<br />
remPoss :: Field -> Field<br />
remPoss f =array ((1,1),(9,9)) $ map remPoss' (assocs f)<br />
where <br />
others xy= filter (/=0) $ row f xy ++ column f xy ++ square f xy<br />
remPoss' ~(i,(xs,n))<br />
| n/=0 = let nxs= filter ( flip notElem (others i) ) xs in (i,(nxs,length $ filter (/=0) nxs))<br />
| otherwise = (i,(xs,n))<br />
<br />
-- remove invalid fields, i.e. contains empty cell without filling possibilities<br />
remInv :: [Field] -> [Field]<br />
remInv = filter (all (\(_,(x,_)) -> x/=[0]).assocs)<br />
<br />
<br />
genMoves :: (Int,Int) -> Field -> [Field]<br />
genMoves xy f = remInv $ map remPoss [f // [(xy,([poss!!i],0))]|i<-[0..num-1]]<br />
where <br />
poss = tail $ fst (f!xy)<br />
num = snd (f!xy)<br />
<br />
--always try the entry with least possibilties first<br />
moves :: Field -> [Field]<br />
moves f = genMoves bestOne f<br />
where<br />
-- remove all with 0 possibilities, select the one with minimum possibilities<br />
bestOne =fst $ minimumBy (\(_,(_,n)) (_,(_,m)) -> compare n m) list <br />
list = ((filter (\(_,(_,x)) -> x/=0).assocs) f)<br />
<br />
play :: [Field] -> Maybe Field<br />
play (f:a)<br />
| done f= Just f<br />
| otherwise = play (moves f++a)<br />
play [] = Nothing<br />
<br />
-- reads a file with puzzles, path as argument<br />
main :: IO ()<br />
main = do <br />
path <- getArgs<br />
inp<-readFile (path!!0)<br />
let x=lines inp<br />
let erg=map (printField.play) (map ((\x->[x]).remPoss.readField) x)<br />
writeFile "./out.txt" (unlines erg)<br />
</haskell><br />
<br />
I let it run on the 41747 minimal puzzles. On a 2.66 GHz Intel Xeon it took 15441m1.920s, which is about 22 seconds per puzzle. It could probably be further improved by making remPoss smarter. At the time of writing this the naive version from which I started is crunching for 20 ''days'' on a simple puzzle with 32 hints. I'd say that's quite a performance improvement.<br />
<br />
== Solving Every Sudoku Puzzle ==<br />
<br />
By Manu<br />
<br />
This is an attempt to implement in Haskell, Peter Norvig's sudoku solver :<br />
more explanations here : http://norvig.com/sudoku.html<br />
<br />
This program greatly benefited from Daniel Fischer's refactoring (80 times faster !).<br />
It takes just above 1 second, on a MacBook Pro 2.33GHz Intel Core 2 Duo, to solve the 95 puzzles found here : http://norvig.com/top95.txt<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Data.List hiding (lookup)<br />
import Data.Array<br />
import Control.Monad<br />
import Data.Maybe<br />
<br />
--------------------------------------------------<br />
-- Types<br />
type Digit = Char<br />
type Square = (Char,Char)<br />
type Unit = [Square]<br />
<br />
-- We represent our grid as an array<br />
type Grid = Array Square [Digit]<br />
<br />
<br />
--------------------------------------------------<br />
-- Setting Up the Problem<br />
<br />
rows = "ABCDEFGHI"<br />
cols = "123456789"<br />
digits = "123456789"<br />
box = (('A','1'),('I','9'))<br />
<br />
cross :: String -> String -> [Square]<br />
cross rows cols = [ (r,c) | r <- rows, c <- cols ]<br />
<br />
squares :: [Square]<br />
squares = cross rows cols -- [('A','1'),('A','2'),('A','3'),...]<br />
<br />
peers :: Array Square [Square]<br />
peers = array box [(s, set (units!s)) | s <- squares ]<br />
where<br />
set = nub . concat<br />
<br />
unitlist :: [Unit]<br />
unitlist = [ cross rows [c] | c <- cols ] ++<br />
[ cross [r] cols | r <- rows ] ++<br />
[ cross rs cs | rs <- ["ABC","DEF","GHI"], <br />
cs <- ["123","456","789"]]<br />
<br />
-- this could still be done more efficiently, but what the heck...<br />
units :: Array Square [Unit]<br />
units = array box [(s, [filter (/= s) u | u <- unitlist, elem s u ]) | <br />
s <- squares]<br />
<br />
<br />
allPossibilities :: Grid<br />
allPossibilities = array box [ (s,digits) | s <- squares ]<br />
<br />
--------------------------------------------------<br />
-- Parsing a grid into an Array<br />
<br />
parsegrid :: String -> Maybe Grid<br />
parsegrid g = do regularGrid g<br />
foldM assign allPossibilities (zip squares g)<br />
<br />
where regularGrid :: String -> Maybe String<br />
regularGrid g = if all (\c -> (elem c "0.-123456789")) g<br />
then (Just g)<br />
else Nothing<br />
<br />
--------------------------------------------------<br />
-- Propagating Constraints<br />
<br />
assign :: Grid -> (Square, Digit) -> Maybe Grid<br />
assign g (s,d) = if (elem d digits)<br />
-- check that we are assigning a digit and not a '.'<br />
then do<br />
let ds = g ! s<br />
toDump = delete d ds<br />
foldM eliminate g (zip (repeat s) toDump)<br />
else return g<br />
<br />
eliminate :: Grid -> (Square, Digit) -> Maybe Grid<br />
eliminate g (s,d) = <br />
let cell = g ! s in<br />
if not (elem d cell) then return g -- already eliminated<br />
-- else d is deleted from s' values<br />
else do let newCell = delete d cell<br />
newV = g // [(s,newCell)]<br />
newV2 <- case newCell of<br />
-- contradiction : Nothing terminates the computation<br />
[] -> Nothing<br />
-- if there is only one value left in s, remove it from peers<br />
[d'] -> do let peersOfS = peers ! s<br />
foldM eliminate newV (zip peersOfS (repeat d'))<br />
-- else : return the new grid<br />
_ -> return newV<br />
-- Now check the places where d appears in the peers of s<br />
foldM (locate d) newV2 (units ! s)<br />
<br />
locate :: Digit -> Grid -> Unit -> Maybe Grid<br />
locate d g u = case filter (elem d . (g !)) u of<br />
[] -> Nothing<br />
[s] -> assign g (s,d)<br />
_ -> return g<br />
<br />
--------------------------------------------------<br />
-- Search<br />
<br />
search :: Grid -> Maybe Grid<br />
search g = <br />
case [(l,(s,xs)) | (s,xs) <- assocs g, let l = length xs, l /= 1] of<br />
[] -> return g<br />
ls -> do let (_,(s,ds)) = minimum ls<br />
msum [assign g (s,d) >>= search | d <- ds]<br />
<br />
solve :: String -> Maybe Grid<br />
solve str = do<br />
grd <- parsegrid str<br />
search grd<br />
<br />
--------------------------------------------------<br />
-- Display solved grid<br />
<br />
printGrid :: Grid -> IO ()<br />
printGrid = putStrLn . gridToString<br />
<br />
gridToString :: Grid -> String<br />
gridToString g =<br />
let l0 = elems g<br />
-- [("1537"),("4"),...] <br />
l1 = (map (\s -> " " ++ s ++ " ")) l0<br />
-- ["1 "," 2 ",...] <br />
l2 = (map concat . sublist 3) l1<br />
-- ["1 2 3 "," 4 5 6 ", ...]<br />
l3 = (sublist 3) l2<br />
-- [["1 2 3 "," 4 5 6 "," 7 8 9 "],...] <br />
l4 = (map (concat . intersperse "|")) l3<br />
-- ["1 2 3 | 4 5 6 | 7 8 9 ",...]<br />
l5 = (concat . intersperse [line] . sublist 3) l4<br />
in unlines l5 <br />
where sublist n [] = []<br />
sublist n xs = take n xs : sublist n (drop n xs)<br />
line = hyphens ++ "+" ++ hyphens ++ "+" ++ hyphens<br />
hyphens = take 9 (repeat '-')<br />
<br />
--------------------------------------------------<br />
<br />
main :: IO ()<br />
main = do<br />
grids <- fmap lines $ readFile "top95.txt"<br />
mapM_ printGrid $ mapMaybe solve grids<br />
</haskell><br />
<br />
== Concurrent STM Solver ==<br />
<br />
[[Liyang]] wrote some [[Liyang/sudoku.hs|applicative functor porn utilising STM]]. It's pretty but slow. Suggestions for speeding it up would be very welcome.<br />
<br />
== Chaining style Solver ==<br />
<br />
by jinjing<br />
<br />
It uses [http://github.com/nfjinjing/projectt/tree/master/T/Snippets.hs some snippets] and the [http://github.com/nfjinjing/projectt/tree/master/T/Hack/Dot.hs dot hack]<br />
<br />
<haskell><br />
import Prelude hiding ((.))<br />
import T.T<br />
import List<br />
import Data.Maybe<br />
import Data.Char<br />
import Data.Map(keys, elems)<br />
import qualified Data.Map as Map<br />
<br />
row i = i `div` 9<br />
col i = i `mod` 9<br />
row_list i positions = positions.select(on_i_row) where<br />
on_i_row pos = pos.row == i.row<br />
col_list i positions = positions.select(on_i_col) where<br />
on_i_col pos = pos.col == i.col<br />
<br />
grid_list i positions = positions.select(on_same_grid i)<br />
<br />
on_same_grid i j = on_same_row_grid i j && on_same_col_grid i j<br />
<br />
on_same_row_grid i j = ( i.row.mod.send_to(3) - j.row.mod.send_to(3) ) == i.row - j.row<br />
on_same_col_grid i j = ( i.col.mod.send_to(3) - j.col.mod.send_to(3) ) == i.col - j.col<br />
<br />
board = 0.upto 80<br />
choices = 1.upto 9<br />
<br />
related i positions = <br />
positions.row_list(i) ++ positions.col_list(i) ++ positions.grid_list(i)<br />
values moves positions = positions.mapMaybe (moves.let_receive Map.lookup)<br />
<br />
possible_moves i moves = <br />
let positions = moves.keys in<br />
choices \\ positions.related(i).values(moves)<br />
<br />
sudoku_move moves = <br />
let i = moves.next_pos in<br />
moves.possible_moves(i).map(Map.insert i).map_send_to(moves)<br />
<br />
next_pos moves = (board \\ moves.keys)<br />
.label_by(choice_size).sort.first.snd where<br />
choice_size i = moves.possible_moves(i).length<br />
<br />
solve solutions 0 = solutions<br />
solve solutions n = solve next_solutions (n-1) where<br />
next_solutions = solutions.map(sudoku_move).concat<br />
<br />
parse_input line = line.words.join("")<br />
.map(\c -> if '1' <= c && c <= '9' then c else '0')<br />
.map(digitToInt).zip([0..]).reject(\(a,b) -> b == 0).Map.fromList<br />
<br />
pretty_output solution = solution.elems.map(show).in_group_of(9)<br />
.map(unwords).unlines<br />
<br />
sudoku line = solve [given] (81 - given.Map.size).first.pretty_output<br />
where given = parse_input line<br />
</haskell><br />
<br />
== Finite Domain Constraint Solver ==<br />
<br />
by David Overton<br />
<br />
This solver uses a finite domain constraint solver monad described [http://overtond.blogspot.com/2008/07/pre.html here].<br />
The core functions are shown below. A full explanation is [http://overtond.blogspot.com/2008/07/haskell-sudoku-solver-using-finite.html here].<br />
<haskell><br />
type Puzzle = [Int]<br />
<br />
sudoku :: Puzzle -> [Puzzle]<br />
sudoku puzzle = runFD $ do<br />
vars <- newVars 81 [1..9]<br />
zipWithM_ (\x n -> when (n > 0) (x `hasValue` n)) vars puzzle<br />
mapM_ allDifferent (rows vars)<br />
mapM_ allDifferent (columns vars)<br />
mapM_ allDifferent (boxes vars)<br />
labelling vars<br />
<br />
rows, columns, boxes :: [a] -> [[a]]<br />
rows = chunk 9<br />
columns = transpose . rows<br />
boxes = concat . map (map concat . transpose) . chunk 3 . chunk 3 . chunk 3<br />
<br />
chunk :: Int -> [a] -> [[a]]<br />
chunk _ [] = []<br />
chunk n xs = ys : chunk n zs where<br />
(ys, zs) = splitAt n xs<br />
</haskell><br />
<br />
== Add your own ==<br />
<br />
If you have a Sudoku solver you're proud of, put it here. This ought to be a good way of helping people learn some fun, intermediate-advanced techniques in Haskell.<br />
<br />
== Test boards ==<br />
<br />
Here's an input file to test the solvers on. Zeroes represent blanks.<br />
<pre><br />
0 5 0 0 6 0 0 0 1<br />
0 0 4 8 0 0 0 7 0<br />
8 0 0 0 0 0 0 5 2<br />
2 0 0 0 5 7 0 3 0<br />
0 0 0 0 0 0 0 0 0<br />
0 3 0 6 9 0 0 0 5<br />
7 9 0 0 0 0 0 0 8<br />
0 1 0 0 0 6 5 0 0<br />
5 0 0 0 3 0 0 6 0<br />
</pre><br />
<br />
A nefarious one:<br />
<br />
<pre><br />
0 0 0 0 6 0 0 8 0<br />
0 2 0 0 0 0 0 0 0<br />
0 0 1 0 0 0 0 0 0<br />
0 7 0 0 0 0 1 0 2<br />
5 0 0 0 3 0 0 0 0<br />
0 0 0 0 0 0 4 0 0<br />
0 0 4 2 0 1 0 0 0<br />
3 0 0 7 0 0 6 0 0<br />
0 0 0 0 0 0 0 5 0 <br />
</pre><br />
<br />
Chris Kuklewicz writes, "You can get over 47,000 distict minimal puzzles from<br />
[http://www.csse.uwa.edu.au/~gordon/sudokumin.php csse.uwa.edu] that have only 17 clues. Then you can run all of them through your program to locate the most evil ones, and use them on your associates."</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Haskell_logos/New_logo_ideas&diff=24998
Haskell logos/New logo ideas
2008-12-18T04:34:59Z
<p>CaleGibbard: </p>
<hr />
<div>'''The great 2009 Haskell logo contest'''<br />
<br />
The Haskell logo has [http://www.willamette.edu/~fruehr/logos/intro.html changed over time], and the current "new" logo reflects the<br />
advanced features of Haskell. However, it is looking rather dated, and doesn't necessarily reflect the mature Haskell we have now.<br />
<br />
So, time to find a new logo. Something reflecting the modern emphasis of<br />
Haskell on purity and simplicity.<br />
<br />
Please submit logo-sized (not overly large) versions of your logo with optional text, with a preferably white background (such as for use on haskell.org).<br />
<br />
Please submit your entries here, and attach your name to them please. To be eligible,<br />
you will need to upload them. Entries not displayed here won't be eligible.<br />
<br />
''The deadline for submissions is December 31, 2008, after which the top few submissions will be voted on by the community to decide a winner!''<br />
<br />
----<br />
<br />
[[Image:haskell-cjay2.png]]<br />
<br />
Available as [[Media:Haskell-cjay2.svg|svg]] (inkscape). Fonts: FreeSerif for lambda, >> and the arrow head; Impact Label for "Haskell" (all free).<br />
<br />
[[User:Cjay|cjay]] 03:49, 18 December 2008 (UTC)<br />
<br />
----<br />
<br />
My attempt at a new Haskell logo:<br />
<br />
[[Image:Haskell_jdr.png]]<br />
<br />
So I guess the standalone version would then be:<br />
<br />
[[Image:Haskell_h_jdr.png]]<br />
<br />
[http://www.voetsjoeba.com Jeroen De Ridder]<br />
<br />
----<br />
<br />
[http://galois.com/~dons/images/logo-3-curved.png http://galois.com/~dons/images/logo-3-curved.png]<br />
<br />
[http://article.gmane.org/gmane.comp.lang.haskell.cafe/49072 George Pollard]<br />
<br />
----<br />
<br />
[[Image:Jeff-heard-1.png]]<br />
<br />
[http://thread.gmane.org/gmane.comp.lang.haskell.cafe/48892/focus=48893 Jeff Heard]. <br />
<br />
----<br />
<br />
Here's an attempt to depict the polish, elegance, and purity of Haskell by merging the H and lambda into an iconic gem.<br />
<br />
[[Image:Haskell2v3.png]]<br />
<br />
Made in Inkscape, with an SVG available.<br />
<br />
--[[User:Chromakode|Chromakode]] 03:18, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
All credit goes to Darrin Thompson for posting the ASCII inspiration for this to haskell-cafe. I, Jeff Wheeler, just mocked it up to look<br />
pretty. Here are two interpretations:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo1.png http://media.nokrev.com/junk/haskell-logos/logo1.png]<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo2.png http://media.nokrev.com/junk/haskell-logos/logo2.png]<br />
<br />
Two with rounded edges:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo8.png http://media.nokrev.com/junk/haskell-logos/logo8.png]<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo9.png http://media.nokrev.com/junk/haskell-logos/logo9.png]<br />
<br />
Here's a icon-sized version:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo4.png http://media.nokrev.com/junk/haskell-logos/logo4.png]<br />
<br />
The first two without an background:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo6.png http://media.nokrev.com/junk/haskell-logos/logo6.png] [http://media.nokrev.com/junk/haskell-logos/logo7.png http://media.nokrev.com/junk/haskell-logos/logo7.png]<br />
<br />
--[[User:Jeffwheeler|Jeffwheeler]] 02:42, 17 December 2008 (UTC)<br />
----<br />
Mix and match<br />
<br />
[http://relapse-software.net/haskell_7.png http://relapse-software.net/haskell_7.png]<br />
----<br />
More mix and match, borrowing bind-lambda icon, star/flower idea, and font/verbiage from other submissions...(Raspoutine Classic font, [[Media:Haskell-Symstar.svg|SVG]] available).<br />
[[Image:Haskell-Symstar.png|Haskell - Logo variant]]<br />
<br />
--[[User:Rgreayer|Rgreayer]] 21:39, 17 December 2008 (UTC)<br />
----<br />
I really like the logo above. Here are some variations. The font name is ModeNine.<br />
<br />
<br />
[[Image:Haskellvariations1.jpg|Haskell - Logo Variations A]]<br />
<br />
[[Image:Haskellvariations2.jpg|Haskell - Logo Variations B]]<br />
<br />
--[[User:Reified|Reified]] 14:48, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
A different logo idea, using toddler's letter blocks to convey the simplicity of Haskell. Exact block look and font used can be changed,<br />
but this is the basic idea.<br />
<br />
[[Image:Haskell_logo_ideas_4_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 23:29, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Stupidb123logo.jpg]]<br />
<br />
--[[User:Stupidb123|Stupidb123]] 12:40, 16 December 2008 (UTC)<br />
<br />
----<br />
"The lightbulb lady" (concept: a lady/lightbulb made out of an inverted lambda, hope it catches...).<br />
Font: Museo Sans 500 (free of charge, add to the cart [http://new.myfonts.com/fonts/exljbris/museo-sans/500/ here]).<br />
<br />
[[Image:The_lady.png]]<br />
<br />
-- [[User:eu-prleu-peupeu]]<br />
----<br />
Just another version of the initial spreadshirt variant. <br />
The black background is now part of the logo. The text should be optional.<br />
<br />
[[Image:haskell_spreadshirt_logo.png|400px]]<br />
<br />
[[User:Frosch03|Frosch03]] 11:41, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
Made with Inkscape. The source in SVG is available [http://www.gburri.org/bordel/logo_haskell_gburri.svg here].<br />
Font : [http://www.dafont.com/raspoutine.font?nb_ppp=50&text=Haskell Raspoutine (free)].<br />
<br />
[[Image:haskel_logo_preview_gburri.png]]<br />
<br />
[[User:Gburri|Gburri]] 09:58, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
Closer to what I had in mind originally:<br />
<br />
[[Image:Haskell-flower3.png]]<br />
<br />
<br />
Probably went too far:<br />
<br />
[[Image:Haskell-flower2.png]]<br />
<br />
<br />
First attempt:<br />
<br />
[[Image:Haskell-flower.png]]<br />
<br />
--[[User:Tanimoto|tanimoto]] 06:09, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
A different take on the lambda-in-a-circle logo that looks less like the Half Life logo. Probably fits better than the monadic sequence<br />
operator in my other submission.<br />
<br />
[[Image:Haskell_logo_ideas_2_falconnl.png]]<br />
<br />
Update:<br />
Slight change and added letters, this time in the free Fonce Sans [http://liquisoft.deviantart.com/art/Fonce-Sans-Regular-Trial-25092730]<br />
font. I like Officina better, but if the font has to be free this is a reasonable substitute.<br />
<br />
[[Image:Haskell_logo_idea_3_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 08:34, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
Very quick attempt:<br />
<br />
[[Image:BurkeLibbey_Haskell.png]]<br />
<br />
The main font is [http://www.josbuivenga.demon.nl/diavlo.html Diavlo] (free). The lambda is in Candara, which I believe ships with Vista<br />
and/or XP. Not sure of the licensing there. If there's significant interest in this, I'll redo it as a vector graphic.<br />
<br />
-- [[User:Burke|Burke]] 02:33, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
On behalf of the Ministry of Safety and Happiness I would like to promote the meme suggesting that Haskell is the programming language of<br />
choice for the Illuminati.<br />
<br />
[[Image:Haskell proceed.png]]<br />
<br />
--[[User:CznpyHrnjwczky|CznpyHrnjwczky]] 05:31, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
More of a mascotte, though she could be used in a logo as well.<br />
<br />
This is Monica Monad, and she's a Warm Fuzzy Thing. Just giving a face to SPJ's alternative name for monads :)<br />
<br />
Her main purpose would be to present tutorials.<br />
<br />
[[Image:Monica_monad_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 00:52, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
A slightly different take on the Haskell logo, as the lambda-in-a-circle looks a bit too much like the Half Life logo for my taste. This<br />
one references monads instead of lambda calculus. Three possible slogans, emphasizing the fun that comes from programming in Haskell.<br />
Number 2 and 3 also reference function composition. Number 3 is my personal favourite.<br />
<br />
[[Image:Haskell_logo_ideas_falconnl.png]]<br />
<br />
Update: a combination of my two logos on a t-shirt. This time with function arrows to indicate the causal relationships: because Haskell is<br />
pure, it's simple. Because it's simple, it's fun.<br />
<br />
[[Image:Haskell_logo_ideas_tshirt_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 22:58, 15 December 2008 (GMT +1)<br />
<br />
: Yummy. What's the font? Is it free? [[User:Porges|Porges]] 21:59, 15 December 2008 (UTC)<br />
: Unfortunately, no. The font is called Officina Sans. Is that a problem? [[User:FalconNL|FalconNL]] 00:02, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
Simple, clean:<br />
<br />
[http://hpsg.fu-berlin.de/~rsling/img/haskell-shirt.jpeg http://hpsg.fu-berlin.de/~rsling/img/haskell-shirt.jpeg]<br />
<br />
I really like this t-shirt logo, by the way. Gets my vote so far. — [[User:Chrisdone|Chrisdone]] 00:18, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
Minor tweak to the above:<br />
<br />
[[Image:HaskellLogo-v2.png]]<br />
<br />
----<br />
<br />
Minor modification of the t-shirt logo, the lambda was a bit skewed in my opinion:<br />
<br />
[[Image:tshirt-logo-mod.png]]<br />
<br />
And another modification of the same theme:<br />
<br />
[[Image:tshirt-logo-mod-inv.png]]<br />
<br />
--[[User:Sebastiaan|Sebastiaan]] 13:29, 15 December 2008 (UTC)<br />
: I really like this one. A font other than Arial would be nice ;) [[User:Porges|Porges]] 21:25, 15 December 2008 (UTC)<br />
<br />
[[Image:HaskellLogoTShirtWhite.png]] -- [[User:Chrisdone|Chrisdone]] 23:19, 15 December 2008 (UTC)<br />
<br />
<br />
<br />
----<br />
<br />
Some ideas. Supposed to resemble a lambda abstraction. I realise there are no formal parameters. ---- [[User:Chrisdone|Chrisdone]] 00:12,<br />
15 December 2008 (UTC)<br />
<br />
[http://chrisdone.com/haskell-blah.png http://chrisdone.com/haskell-blah-thumb.png]<br />
<br />
----<br />
<br />
Here's another one; lambda is Gentium SIL, Haskell is MgOpen Cosmetica, tagline is MgOpen Canonica Italic. [[User:Porges|Porges]] 21:25, 15<br />
December 2008 (UTC)<br />
<br />
[[Image:Haskell Logo.png]]<br />
<br />
----<br />
<br />
Another take. A bit simpler, more symmetrical.<br />
<br />
[[Image:haskelllogobeshers.png]]<br />
<br />
----<br />
<br />
[[Image:Haskell-logo.png]]<br />
<br />
The logo uses Kautiva Bold as (non-free) font.<br />
<br />
--[[User:Eelco|Eelco]] 07:43, 15 December 2008 (UTC)<br />
<br />
This one is dedicated to Derek Elkins, to sooth his eyes after having them hurt on the previous logo:<br />
<br />
[[Image:Haskell-logo-funny.png]]<br />
<br />
--[[User:Eelco|Eelco]] 08:53, 15 December 2008 (UTC)<br />
: Makes sense. Comic Sans is the *Official Font of Haskell*, after all.<br />
<br />
----<br />
[[Image:HaskellLogoTDavie.png]]<br />
<br />
[[Image:HaskellLogoTDavie.pdf]] (vector pdf version)<br />
<br />
[[Image:HaskellLogoTDavie2.png]]<br />
<br />
[[User:Beelsebob|Beelsebob]] 08:32, 15 December 2008 (UTC)<br />
<br />
---- <br />
<br />
[http://relapse-software.net/haskell_0.png http://relapse-software.net/haskell_0.png]<br />
<br />
[http://relapse-software.net/haskell_1.png http://relapse-software.net/haskell_1.png]<br />
<br />
----<br />
<br />
[http://relapse-software.net/haskell_5.png http://relapse-software.net/haskell_5.png]<br />
<br />
<br />
[http://relapse-software.net/haskell_2.png http://relapse-software.net/haskell_2.png]<br />
<br />
[http://relapse-software.net/haskell_3.png http://relapse-software.net/haskell_3.png]<br />
<br />
----<br />
<br />
Logo fun using Blender:<br />
<br />
[[Image:HsLogosMB.png|center|Haskell Logo idea with lambda as mascot]]<br />
<br />
I tried to give the lambda sign an ''alive'' feeling. --[[User:GokhanSan|GokhanSan]] 12:49, 15 December 2008 (UTC)<br />
: Middle one looks a bit too much like the ghostbusters logo :D [[User:Porges|Porges]] 21:25, 15 December 2008 (UTC)<br />
:: Hmm, I wonder if it's the choice of colors. Then again, with a minor alteration, we get a FreeBSD icon candidate:<br />
[[Image:HsLogoMB-BSD.png|beastie]] ;-) --[[User:GokhanSan|GokhanSan]] 08:52, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:HaskellLogoIdea05.gif]]<br />
<br />
Not sure about the colour. I tried to pick the purple from the current logo. Although the lower lambda is rotated there is<br />
[http://poinikastas.csad.ox.ac.uk/browseGlyphs.shtml historic precedence] for other forms of the letter. The lambda takes the angle from<br />
the 'k'. Font is News Gothic. Feel free to play with the concept. [[User:Rk|Rk]] 11:13, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
<br />
More vectorial Haskell logo concepts. Using inkscape and the popular [http://inde-graphics.deviantart.com/art/advent-font-57338302 advent<br />
font] (CC at-nc-nd).<br />
<br />
[[Image:Haskell_infinitylambda.png]]<br />
[[Image:Haskell_halfhalfinfinitylambda.png]]<br />
[[Image:Haskell_3qhalfinfinitylambda.png]]<br />
<br />
Vectorial images (svg):<br />
<br />
[http://haskell.org/sitewiki/images/8/86/Haskell_infinitylambda.svg 1]<br />
[http://haskell.org/sitewiki/images/d/df/Haskell_halfinfinitylambda.svg 2]<br />
[http://haskell.org/sitewiki/images/6/66/Haskell_3qhalfinfinitylambda.svg 3]<br />
<br />
* [[User:alvivi|alvivi]] 19:28, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Haskell-pure.png|haskell::pure]]<br />
<br />
--[[User:Rgreayer|Rgreayer]] 20:44, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
Find a font where 'k' looks like a reverse lambda (after removing the "stalk"). For example:<br />
<br />
[[Image:Kaskell.png|Kaskell]]<br />
<br />
Note this example uses Monotype Corsiva which is not a free font. If the basic approach looks good, we can find a similar free font that<br />
works.<br />
<br />
--[[User:Orenbenkiki|OrenBenKiki]] 01:40, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Haskell.png|Haskellll]]<br />
<br />
Illustrator, vector art available, apologies to GokhanSan<br />
<br />
--[[User:Mpeter|Mpeter]] 10:18, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
<br />
[http://relapse-software.net/haskell_6.png http://relapse-software.net/haskell_6.png]<br />
<br />
----<br />
<br />
[[Image:Haskell3.png|Haskell]]<br />
[[Image:Haskell4.png|Haskell]]<br />
<br />
Inkscape, vector art available.<br />
<br />
--[[User:Chromakode|Chromakode]] 07:14, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
I'll probably regret this...<br />
<br />
[[Image:NarleyYeeaaahh.jpg|Haskell - Narwals, YEEAAAAHH!!]]<br />
<br />
(Created with PAINT.NET)<br />
<br />
--[[User:Reified|Reified]] 07:20, 16 December 2008 (UTC)<br />
----<br />
<br />
The general idea is that it's just "Haskell" but with w lambda instead of the a. The font here is Myriad Pro but this would work with any<br />
good sans-serif font. It's color-agnostic, so it can be easily printer, presented as white on black or changed to a different color.<br />
<br />
[[Image:Haskell_logo_bonus.png]]<br />
<br />
[[Image:Haskell_logo_bonus2.png]]<br />
<br />
--[[User:BONUS|BONUS]] 14:40, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Axman6-logo-1.0.png]]<br />
<br />
--[[User:Axman6|Axman6]] 15:16, 16 December 2008 (UTC)<br />
<br />
<br />
[[image:Haskell_girl.jpg]]<br />
<br />
<br />
Oh, didn't know png's would work.<br />
--[[User:Tindrum|Tindrum]] 17:12, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Haskell_logo.png]]<br />
<br />
It is mutually recursive...<br />
Here is the [[Media:Haskell logo.svg|svg]].<br />
<br />
Second version:<br />
<br />
[[image:Haskell2_logo.png]]<br />
<br />
And the [[Media:Haskell2 logo.svg|svg]].<br />
<br />
--[[User:Trontonic|Trontonic]] 20:39, 16 December 2008 (UTC)<br />
<br />
----<br />
This is a variation on my [http://t-shirts.cafepress.com/item/lambda-revolution-fitted-tshirt/96543210 Cafepress t-shirt]. The PNG is<br />
generated from an Inkscape SVG.<br />
<br />
[[Image:Haskell-logo-revolution.png]]<br />
<br />
[[User:PaulJohnson|PaulJohnson]] 21:08, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:haskell-cjay.png]]<br />
<br />
Available as [[Media:Haskell-cjay.svg|svg]] (inkscape). Fonts: FreeSerif for lambda and >>. Bitstream Vera and FreeMono for other (afaik<br />
all free to use)<br />
<br />
[[User:Cjay|cjay]] 22:45, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
http://conal.net/Pan/Gallery/haskell-powered%20on%20white%20tiled%20360.png<br />
<br />
One I made with [http://conal.net/Pan/Gallery Pan] (purely functional image synthesis in Haskell) some years back. See also the<br />
[http://conal.net/Pan/Gallery/haskell-powered%20on%20white%20tiled%20720.png 720 square version]. I have a few sizes up to 2250 pixels<br />
square.<br />
<br />
[[User:Conal|Conal]] 03:40, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Haskell_lambda.png]]<br />
<br />
Just kidding :P<br />
<br />
--[[User:Trontonic|Trontonic]] 05:04, 17 December 2008 (UTC)<br />
<br />
----<br />
=== Cale Gibbard ===<br />
[[Image:Haskell-logo-6up.png]]<br />
<br />
[http://haskell.org/haskellwiki/Image:Haskell-logo-6up.svg Inkscape SVG]<br />
<br />
I originally had no specific mountain in mind, but Don Stewart pointed out that this might be representative of Mt. Hood in Portland, Oregon, where Haskell was named.<br />
<br />
Regardless, I thought a summit, bathed in the pure mountain air would be a decent symbol for Haskell, the peak of contemporary programming. :)<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 05:55, 17 December 2008 (UTC)<br />
:Here's a modified version with a slightly funkier font :) I think that it matches the lines of the image better... [[User:Porges|Porges]] 03:14, 18 December 2008 (UTC)<br />
<br />
[[Image:Testhask.png]]<br />
----<br />
<br />
Probably not a good choice for a logo:<br />
<br />
[[Image:Hazard lambda cracked 2.png]]<br />
<br />
----<br />
<br />
[[Image:Haskell_Ribbons.png]]<br />
<br />
[http://slipgate.za.net/~korpse/misc/Haskell_Ribbons.svg SVG]<br />
<br />
Simplicity.<br />
<br />
(It is possible that the font may need to be replaced with a free alternative.)<br />
<br />
[[User:Jonathanj|JonathanJ]] 16:34, 17 December 2008 (UTC)</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Haskell_logos/New_logo_ideas&diff=24941
Haskell logos/New logo ideas
2008-12-17T05:55:47Z
<p>CaleGibbard: </p>
<hr />
<div>'''The great 2009 Haskell logo contest'''<br />
<br />
The Haskell logo has [http://www.willamette.edu/~fruehr/logos/intro.html changed over time], and the current "new" logo reflects the<br />
advanced features of Haskell. However, it is looking rather dated, and doesn't necessarily reflect the mature Haskell we have now.<br />
<br />
So, time to find a new logo. Something reflecting the modern emphasis of<br />
Haskell on purity and simplicity.<br />
<br />
Please submit logo-sized (not overly large) versions of your logo with optional text, with a preferably white background (such as for use on haskell.org).<br />
<br />
Please submit your entries here, and attach your name to them please. To be eligible,<br />
you will need to upload them. Entries not displayed here won't be eligible.<br />
<br />
''The deadline for submissions is December 31, 2008, after which the top few submissions will be voted on by the community to decide a winner!''<br />
<br />
----<br />
<br />
Here's an attempt to depict the polish, elegance, and purity of Haskell by merging the H and lambda into an iconic gem.<br />
<br />
[[Image:Haskell2v3.png]]<br />
<br />
Made in Inkscape, with an SVG available.<br />
<br />
--[[User:Chromakode|Chromakode]] 03:18, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
All credit goes to Darrin Thompson for posting the ASCII inspiration for this to haskell-cafe. I, Jeff Wheeler, just mocked it up to look<br />
pretty. Here are two interpretations:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo1.png http://media.nokrev.com/junk/haskell-logos/logo1.png]<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo2.png http://media.nokrev.com/junk/haskell-logos/logo2.png]<br />
<br />
Here's a icon-sized version:<br />
<br />
[http://media.nokrev.com/junk/haskell-logos/logo4.png http://media.nokrev.com/junk/haskell-logos/logo4.png]<br />
<br />
--[[User:Jeffwheeler|Jeffwheeler]] 02:42, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
A different logo idea, using toddler's letter blocks to convey the simplicity of Haskell. Exact block look and font used can be changed,<br />
but this is the basic idea.<br />
<br />
[[Image:Haskell_logo_ideas_4_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 23:29, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Stupidb123logo.jpg]]<br />
<br />
--[[User:Stupidb123|Stupidb123]] 12:40, 16 December 2008 (UTC)<br />
<br />
----<br />
"The lightbulb lady" (concept: a lady/lightbulb made out of an inverted lambda, hope it catches...).<br />
Font: Museo Sans 500 (free of charge, add to the cart [http://new.myfonts.com/fonts/exljbris/museo-sans/500/ here]).<br />
<br />
[[Image:The_lady.png]]<br />
<br />
-- [[User:eu-prleu-peupeu]]<br />
----<br />
Just another version of the initial spreadshirt variant. <br />
The black background is now part of the logo. The text should be optional.<br />
<br />
[[Image:haskell_spreadshirt_logo.png|400px]]<br />
<br />
[[User:Frosch03|Frosch03]] 11:41, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
Made with Inkscape (SVG). Font : Calibri.<br />
<br />
[[Image:Haskell logo v1.png]]<br />
<br />
[[Image:Haskell logo v2.png]]<br />
<br />
[[User:Gburri|Gburri]] 09:58, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
Lambdas in a circle:<br />
<br />
[[Image:Haskell-flower.png]]<br />
<br />
<br />
Closer to what I had in mind originally:<br />
<br />
[[Image:Haskell-flower3.png]]<br />
<br />
--[[User:Tanimoto|tanimoto]] 07:43, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
A different take on the lambda-in-a-circle logo that looks less like the Half Life logo. Probably fits better than the monadic sequence<br />
operator in my other submission.<br />
<br />
[[Image:Haskell_logo_ideas_2_falconnl.png]]<br />
<br />
Update:<br />
Slight change and added letters, this time in the free Fonce Sans [http://liquisoft.deviantart.com/art/Fonce-Sans-Regular-Trial-25092730]<br />
font. I like Officina better, but if the font has to be free this is a reasonable substitute.<br />
<br />
[[Image:Haskell_logo_idea_3_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 08:34, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
Very quick attempt:<br />
<br />
[[Image:BurkeLibbey_Haskell.png]]<br />
<br />
The main font is [http://www.josbuivenga.demon.nl/diavlo.html Diavlo] (free). The lambda is in Candara, which I believe ships with Vista<br />
and/or XP. Not sure of the licensing there. If there's significant interest in this, I'll redo it as a vector graphic.<br />
<br />
-- [[User:Burke|Burke]] 02:33, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
On behalf of the Ministry of Safety and Happiness I would like to promote the meme suggesting that Haskell is the programming language of<br />
choice for the Illuminati.<br />
<br />
[[Image:Haskell proceed.png]]<br />
<br />
--[[User:CznpyHrnjwczky|CznpyHrnjwczky]] 05:31, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
More of a mascotte, though she could be used in a logo as well.<br />
<br />
This is Monica Monad, and she's a Warm Fuzzy Thing. Just giving a face to SPJ's alternative name for monads :)<br />
<br />
Her main purpose would be to present tutorials.<br />
<br />
[[Image:Monica_monad_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 00:52, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
A slightly different take on the Haskell logo, as the lambda-in-a-circle looks a bit too much like the Half Life logo for my taste. This<br />
one references monads instead of lambda calculus. Three possible slogans, emphasizing the fun that comes from programming in Haskell.<br />
Number 2 and 3 also reference function composition. Number 3 is my personal favourite.<br />
<br />
[[Image:Haskell_logo_ideas_falconnl.png]]<br />
<br />
Update: a combination of my two logos on a t-shirt. This time with function arrows to indicate the causal relationships: because Haskell is<br />
pure, it's simple. Because it's simple, it's fun.<br />
<br />
[[Image:Haskell_logo_ideas_tshirt_falconnl.png]]<br />
<br />
--[[User:FalconNL|FalconNL]] 22:58, 15 December 2008 (GMT +1)<br />
<br />
: Yummy. What's the font? Is it free? [[User:Porges|Porges]] 21:59, 15 December 2008 (UTC)<br />
: Unfortunately, no. The font is called Officina Sans. Is that a problem? [[User:FalconNL|FalconNL]] 00:02, 16 December 2008 (GMT +1)<br />
<br />
----<br />
<br />
Simple, clean:<br />
<br />
[http://hpsg.fu-berlin.de/~rsling/img/haskell-shirt.jpeg http://hpsg.fu-berlin.de/~rsling/img/haskell-shirt.jpeg]<br />
<br />
I really like this t-shirt logo, by the way. Gets my vote so far. — [[User:Chrisdone|Chrisdone]] 00:18, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
Minor tweak to the above:<br />
<br />
[[Image:HaskellLogo-v2.png]]<br />
<br />
----<br />
<br />
Minor modification of the t-shirt logo, the lambda was a bit skewed in my opinion:<br />
<br />
[[Image:tshirt-logo-mod.png]]<br />
<br />
And another modification of the same theme:<br />
<br />
[[Image:tshirt-logo-mod-inv.png]]<br />
<br />
--[[User:Sebastiaan|Sebastiaan]] 13:29, 15 December 2008 (UTC)<br />
: I really like this one. A font other than Arial would be nice ;) [[User:Porges|Porges]] 21:25, 15 December 2008 (UTC)<br />
<br />
[[Image:HaskellLogoTShirtWhite.png]] -- [[User:Chrisdone|Chrisdone]] 23:19, 15 December 2008 (UTC)<br />
<br />
<br />
<br />
----<br />
<br />
Some ideas. Supposed to resemble a lambda abstraction. I realise there are no formal parameters. ---- [[User:Chrisdone|Chrisdone]] 00:12,<br />
15 December 2008 (UTC)<br />
<br />
[http://chrisdone.com/haskell-blah.png http://chrisdone.com/haskell-blah-thumb.png]<br />
<br />
----<br />
<br />
Here's another one; lambda is Gentium SIL, Haskell is MgOpen Cosmetica, tagline is MgOpen Canonica Italic. [[User:Porges|Porges]] 21:25, 15<br />
December 2008 (UTC)<br />
<br />
[[Image:Haskell Logo.png]]<br />
<br />
----<br />
<br />
Another take. A bit simpler, more symmetrical.<br />
<br />
[[Image:haskelllogobeshers.png]]<br />
<br />
----<br />
<br />
[[Image:Haskell-logo.png]]<br />
<br />
The logo uses Kautiva Bold as (non-free) font.<br />
<br />
--[[User:Eelco|Eelco]] 07:43, 15 December 2008 (UTC)<br />
<br />
This one is dedicated to Derek Elkins, to sooth his eyes after having them hurt on the previous logo:<br />
<br />
[[Image:Haskell-logo-funny.png]]<br />
<br />
--[[User:Eelco|Eelco]] 08:53, 15 December 2008 (UTC)<br />
: Makes sense. Comic Sans is the *Official Font of Haskell*, after all.<br />
<br />
----<br />
[[Image:HaskellLogoTDavie.png]]<br />
<br />
[[Image:HaskellLogoTDavie.pdf]] (vector pdf version)<br />
<br />
[[User:Beelsebob|Beelsebob]] 08:32, 15 December 2008 (UTC)<br />
<br />
---- <br />
<br />
[http://relapse-software.net/haskell_0.png http://relapse-software.net/haskell_0.png]<br />
<br />
[http://relapse-software.net/haskell_1.png http://relapse-software.net/haskell_1.png]<br />
<br />
----<br />
<br />
[http://relapse-software.net/haskell_5.png http://relapse-software.net/haskell_5.png]<br />
<br />
<br />
[http://relapse-software.net/haskell_2.png http://relapse-software.net/haskell_2.png]<br />
<br />
[http://relapse-software.net/haskell_3.png http://relapse-software.net/haskell_3.png]<br />
<br />
----<br />
<br />
Logo fun using Blender:<br />
<br />
[[Image:HsLogosMB.png|center|Haskell Logo idea with lambda as mascot]]<br />
<br />
I tried to give the lambda sign an ''alive'' feeling. --[[User:GokhanSan|GokhanSan]] 12:49, 15 December 2008 (UTC)<br />
: Middle one looks a bit too much like the ghostbusters logo :D [[User:Porges|Porges]] 21:25, 15 December 2008 (UTC)<br />
:: Hmm, I wonder if it's the choice of colors. Then again, with a minor alteration, we get a FreeBSD icon candidate:<br />
[[Image:HsLogoMB-BSD.png|beastie]] ;-) --[[User:GokhanSan|GokhanSan]] 08:52, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:HaskellLogoIdea05.gif]]<br />
<br />
Not sure about the colour. I tried to pick the purple from the current logo. Although the lower lambda is rotated there is<br />
[http://poinikastas.csad.ox.ac.uk/browseGlyphs.shtml historic precedence] for other forms of the letter. The lambda takes the angle from<br />
the 'k'. Font is News Gothic. Feel free to play with the concept. [[User:Rk|Rk]] 11:13, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
<br />
More vectorial Haskell logo concepts. Using inkscape and the popular [http://inde-graphics.deviantart.com/art/advent-font-57338302 advent<br />
font] (CC at-nc-nd).<br />
<br />
[[Image:Haskell_infinitylambda.png]]<br />
[[Image:Haskell_halfhalfinfinitylambda.png]]<br />
[[Image:Haskell_3qhalfinfinitylambda.png]]<br />
<br />
Vectorial images (svg):<br />
<br />
[http://haskell.org/sitewiki/images/8/86/Haskell_infinitylambda.svg 1]<br />
[http://haskell.org/sitewiki/images/d/df/Haskell_halfinfinitylambda.svg 2]<br />
[http://haskell.org/sitewiki/images/6/66/Haskell_3qhalfinfinitylambda.svg 3]<br />
<br />
* [[User:alvivi|alvivi]] 19:28, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Haskell-pure.png|haskell::pure]]<br />
<br />
--[[User:Rgreayer|Rgreayer]] 20:44, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
Find a font where 'k' looks like a reverse lambda (after removing the "stalk"). For example:<br />
<br />
[[Image:Kaskell.png|Kaskell]]<br />
<br />
Note this example uses Monotype Corsiva which is not a free font. If the basic approach looks good, we can find a similar free font that<br />
works.<br />
<br />
--[[User:Orenbenkiki|OrenBenKiki]] 01:40, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Haskell.png|Haskellll]]<br />
<br />
Illustrator, vector art available, apologies to GokhanSan<br />
<br />
--[[User:Mpeter|Mpeter]] 10:18, 15 December 2008 (UTC)<br />
<br />
----<br />
<br />
<br />
[http://relapse-software.net/haskell_6.png http://relapse-software.net/haskell_6.png]<br />
<br />
----<br />
<br />
[[Image:Haskell3.png|Haskell]]<br />
[[Image:Haskell4.png|Haskell]]<br />
<br />
Inkscape, vector art available.<br />
<br />
--[[User:Chromakode|Chromakode]] 07:14, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
I'll probably regret this...<br />
<br />
[[Image:NarleyYeeaaahh.jpg|Haskell - Narwals, YEEAAAAHH!!]]<br />
<br />
(Created with PAINT.NET)<br />
<br />
--[[User:Reified|Reified]] 07:20, 16 December 2008 (UTC)<br />
----<br />
<br />
The general idea is that it's just "Haskell" but with w lambda instead of the a. The font here is Myriad Pro but this would work with any<br />
good sans-serif font. It's color-agnostic, so it can be easily printer, presented as white on black or changed to a different color.<br />
<br />
[[Image:Haskell_logo_bonus.png]]<br />
<br />
[[Image:Haskell_logo_bonus2.png]]<br />
<br />
--[[User:BONUS|BONUS]] 14:40, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Axman6-logo-1.0.png]]<br />
<br />
--[[User:Axman6|Axman6]] 15:16, 16 December 2008 (UTC)<br />
<br />
<br />
[[image:Haskell_girl.jpg]]<br />
<br />
<br />
Oh, didn't know png's would work.<br />
--[[User:Tindrum|Tindrum]] 17:12, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Haskell_logo.png]]<br />
<br />
It is mutually recursive...<br />
Here is the [[Media:Haskell logo.svg|svg]].<br />
<br />
Second version:<br />
<br />
[[image:Haskell2_logo.png]]<br />
<br />
And the [[Media:Haskell2 logo.svg|svg]].<br />
<br />
--[[User:Trontonic|Trontonic]] 20:39, 16 December 2008 (UTC)<br />
<br />
----<br />
This is a variation on my [http://t-shirts.cafepress.com/item/lambda-revolution-fitted-tshirt/96543210 Cafepress t-shirt]. The PNG is<br />
generated from an Inkscape SVG.<br />
<br />
[[Image:Haskell-logo-revolution.png]]<br />
<br />
[[User:PaulJohnson|PaulJohnson]] 21:08, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:haskell-cjay.png]]<br />
<br />
Available as [[Media:Haskell-cjay.svg|svg]] (inkscape). Fonts: FreeSerif for lambda and >>. Bitstream Vera and FreeMono for other (afaik<br />
all free to use)<br />
<br />
[[User:Cjay|cjay]] 22:45, 16 December 2008 (UTC)<br />
<br />
----<br />
<br />
http://conal.net/Pan/Gallery/haskell-powered%20on%20white%20tiled%20360.png<br />
<br />
One I made with [http://conal.net/Pan/Gallery Pan] (purely functional image synthesis in Haskell) some years back. See also the<br />
[http://conal.net/Pan/Gallery/haskell-powered%20on%20white%20tiled%20720.png 720 square version]. I have a few sizes up to 2250 pixels<br />
square.<br />
<br />
[[User:Conal|Conal]] 03:40, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[image:Haskell_lambda.png]]<br />
<br />
Just kidding :P<br />
<br />
--[[User:Trontonic|Trontonic]] 05:04, 17 December 2008 (UTC)<br />
<br />
----<br />
<br />
[[Image:Haskell-logo-6up.png]]<br />
<br />
[http://haskell.org/haskellwiki/Image:Haskell-logo-6up.svg Inkscape SVG]<br />
<br />
I originally had no specific mountain in mind, but Don Stewart pointed out that this might be representative of Mt. Hood in Portland, Oregon, where Haskell was named.<br />
<br />
Regardless, I thought a summit, bathed in the pure mountain air would be a decent symbol for Haskell, the peak of contemporary programming. :)<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 05:55, 17 December 2008 (UTC)</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=File:Haskell-logo-6up.svg&diff=24937
File:Haskell-logo-6up.svg
2008-12-17T05:38:30Z
<p>CaleGibbard: </p>
<hr />
<div></div>
CaleGibbard
https://wiki.haskell.org/index.php?title=File:Haskell-logo-6up.png&diff=24936
File:Haskell-logo-6up.png
2008-12-17T05:37:51Z
<p>CaleGibbard: </p>
<hr />
<div></div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Why_Haskell_matters&diff=24284
Why Haskell matters
2008-11-26T20:46:31Z
<p>CaleGibbard: </p>
<hr />
<div>==What are functional programming languages?==<br />
Programming languages such as C/C++/Java/Python are called imperative programming languages because they consist of sequences of actions. The programmer quite explicitly tells the computer how to perform a task, step-by-step.<br />
Functional programming languages work differently. Rather than performing actions in a sequence, they evaluate expressions.<br />
<br />
<br />
=== The level of abstraction ===<br />
There are two areas that are fundamental to programming a computer - resource management and sequencing. Resource management (allocating registers and memory) has been the target of vast abstraction, most new languages (imperative as well as functional) have implemented garbage collection to remove resource management from the problem, and lets the programmer focus on the algorithm instead of the book-keeping task of allocating memory.<br />
Sequencing has also undergone some abstraction, although not nearly to the same extent. Imperative languages have done so by introducing new keywords and standard libraries. For example, most imperative languages have special syntax for constructing several slightly different loops, you no longer have to do all the tasks of managing these loops yourself.<br />
But imperative languages are based upon the notion of sequencing - they can never escape it completely. The only way to raise the level of abstraction in the sequencing area for an imperative language is to introduce more keywords or standard functions, thus cluttering up the language.<br />
This close relationship between imperative languages and the task of sequencing commands for the processor to execute means that imperative languages can never rise above the task of sequencing, and as such can never reach the same level of abstraction that functional programming languages can.<br />
<br />
In Haskell, the sequencing task is removed. You only care what the program is to compute not how or when it is computed. This makes Haskell a more flexible and easy to use language. Haskell tends to be part of the solution for a problem, not a part of the problem itself.<br />
<br />
=== Functions and side-effects in functional languages ===<br />
Functions play an important role in functional programming languages. Functions are considered to be values just like Int or String. A function can return another function, it can take a function as a parameter, and it can even be constructed by composing functions.<br />
This offers a stronger "glue" to combine the modules of your program. A function that evaluates some expression can take part of the computation as an argument for instance, thus making the function more modular.<br />
You could also have a function construct another function. For instance, you could define a function "differentiate" that will differentiate a given function numerically. So if you then have a function "f" you could define "f' = differentiate f", and use it like you would normally in a mathematical context.<br />
These types of functions are called ''higher order functions''.<br />
<br />
Here is a short Haskell example of a function numOf that counts the number of elements in a list that satisfy a certain property.<br />
<br />
<haskell>numOf p xs = length (filter p xs)</haskell><br />
<br />
We will discuss Haskell syntax later, but what this line says is just "To get the result, filter the list xs by the test p and compute the length of the result".<br />
Now p is a function that takes an element and returns True or False determining whether the element passes or fails the test. So numOf is a higher order function, some of the functionality is passed to it as an argument. Notice that filter is also a higher order function, it takes the "test function" as an argument.<br />
Let's play with this function and define some more specialized functions from it.<br />
<br />
<haskell>numOfEven xs = numOf even xs</haskell><br />
<br />
Here we define the function numOfEven which counts the number of even elements in a list. Note that we do not need to explicitly declare xs as a parameter. We could just as well write numOfEven = numOf even. A very clear definition indeed. But we'll explicitly type out the parameters for now.<br />
<br />
Let's define a function which counts the number of elements that are greater or equal to 5 :<br />
<br />
<haskell>numOfGE5 xs = numOf (>=5) xs</haskell><br />
<br />
Here the test function is just ">=5" which is passed to numOf to give us the functionality we need.<br />
<br />
Hopefully you should now see that the modularity of functional programming allows us to define a generic functions where some of the functionality is passed as an argument, which we can later use to define shorthands for any specialized functions.<br />
This small example is somewhat trivial, it wouldn't be too hard to re-write the function definition for all the functions above, but for more complex functions this comes in handy.<br />
You can, for instance, write only one function for traversing an auto-balancing binary tree and have it take some of the functionality as a parameter (for instance the comparison function). This would allow you to traverse the tree for any data type by simply providing the relevant comparison function for your needs. Thus you can expend some effort in making sure the general function is correct, and then all the specialized functions will also be correct. Not to mention you wouldn't have to copy and paste code all over your project.<br />
This concept is possible in some imperative languages as well. In some object oriented languages you often have to provide a "Comparator object" for trees and other standard data structures. The difference is that the Haskell way is a lot more intuitive and elegant (creating a separate type just for comparing two other types and then passing an object of this type is hardly an elegant way of doing it), so it's more likely to be used frequently (and not just in the standard libraries).<br />
<br />
A central concept in functional languages is that the result of a function is determined by its input, and only by its input. There are no side-effects! This extends to variables as well - ''variables in Haskell do not vary''. This may sound strange if you're used to imperative programming (where ''most'' of the code consists of changing the "contents" of a variable), but it's really quite natural. A variable in Haskell is a name that is bound to some value, rather than an abstraction of some low-level concept of a memory cell like in imperative languages. When variables are thought of as short-hands for values (just like they are in mathematics), it makes perfect sense that variable updates are not allowed. You wouldn't expect "4 = 5" to be a valid assignment in ''any'' language, so it's really quite strange that "x = 4; x = 5" is.<br />
This is often hard to grasp for programmers who are very used to imperative languages, but it isn't as strange as it first seems. So when you start thinking things like "This is too weird, I'm going back to C++!", try to force yourself to continue learning Haskell - you'll be glad you did.<br />
<br />
<br />
Removing side-effects from the equation allows expressions to be evaluated in any order. A function will always return the same result if passed the same input - no exceptions.<br />
This determinism removes a whole class of bugs found in imperative programs. In fact, you could even argue that ''most'' bugs in large systems can be traced back to side-effects - if not directly caused by them, then caused by a flawed design that relies on side-effects.<br />
This means that functional programs tend to have far fewer bugs than imperative ones.<br />
<br />
<br />
=== Conclusion ===<br />
Because functional languages are more intuitive and offer more and easier ways to get the job done, functional programs tend to be shorter (usually between 2 to 10 times shorter). The semantics are most often a lot closer to the problem than an imperative version, which makes it easier to verify that a function is correct. Furthermore Haskell doesn't allow side-effects, which leads to less bugs. Thus Haskell programs are easier to write, more robust, and easier to maintain.<br />
<br />
== What can Haskell offer the programmer? ==<br />
Haskell is a modern general purpose language developed to incorporate the collective wisdom of the functional programming community into one elegant, powerful and general language.<br />
<br />
===Purity===<br />
Unlike some other functional programming languages Haskell is pure. It doesn't allow ''any'' side-effects. This is probably the most important feature of Haskell. We've already briefly discussed the benefits of pure, side-effect free, programming - and there's not much more we can say about that. You'll need to experience it yourself.<br />
<br />
===Laziness===<br />
Another feature of Haskell is that it is lazy (technically speaking, it's "non-strict"). This means that nothing is evaluated until it has to be evaluated. You could, for instance, define an infinite list of primes without ending up in infinite recursion. Only the elements of this list that are actually used will be computed. This allows for some very elegant solutions to many problems. A typical pattern of solving a problem would be to define a list of all possible solutions and then filtering away the illegal ones. The remaining list will then only contain legal solutions. Lazy evaluation makes this operation very clean. If you only need one solution you can simply extract the first element of the resulting list - lazy evaluation will make sure that nothing is needlessly computed.<br />
<br />
===Strong typing===<br />
Furthermore Haskell is strongly typed, this means just what it sounds like. It's impossible to inadvertently convert a Double to an Int, or follow a null pointer. This also leads to less bugs. It might be a pain in the neck in the rare cases where you need to convert an Int to a Double explicitly before performing some operation, but in practice this doesn't happen often enough to become a nuisance. In fact, forcing each conversion to be explicit often helps to highlight problem code.<br />
In other languages where these conversions are invisible, problems often arise when the compiler treats a double like an integer or, even worse, an integer like a pointer.<br />
<br />
Unlike other strongly typed languages types in Haskell are automatically inferred. This means that you very rarely have to declare the types of your functions, except as a means of code documentation. Haskell will look at how you use the variables and figure out from there what type the variable should be - then it will all be type-checked to ensure there are no type-mismatches. <br />
Python has the notion of "duck typing", meaning "If it walks and talks like a duck, it's a duck!". You could argue that Haskell has a much better form of duck typing. If a value walks and talks like a duck, then it will be considered a duck through type inference, but unlike Python the compiler will also catch errors if later on it tries to bray like a donkey!<br />
So you get the benefits of strong typing (bugs are caught at compile-time, rather than run-time) without the hassle that comes with it in other languages.<br />
Furthermore Haskell will always infer the most general type on a variable. So if you write, say, a sorting function without a type declaration, Haskell will make sure the function will work for all values that can be sorted.<br />
<br />
Compare how you would do this in certain object oriented languages. To gain polymorphism you would have to use some base class, and then declare your variables as instances of subclasses to this base class. It all amounts to tons of extra work and ridiculously complex declarations just to proclaim the existence of a variable. Furthermore you would have to perform tons of type conversions via explicit casts - definitely not a particularly elegant solution.<br />
If you want to write a polymorphic function in these object oriented languages you would probably declare the parameters as an object of a global base class (like "Object" in Java), which essentially allows the programmer to send anything into the function, even objects which can't logically be passed to the function. The end result is that most functions you write in these languages are not general, they only work on a single data type. You're also moving the error checking from compile-time to run-time. In large systems where some of the functionality is rarely used, these bugs might never be caught until they cause a fatal crash at the worst possible time.<br />
<br />
Haskell provides an elegant, concise and safe way to write your programs. Programs will not crash unexpectedly, nor produce strangely garbled output.<br />
<br />
===Elegance===<br />
Another property of Haskell that is very important to the programmer, even though it doesn't mean as much in terms of stability or performance, is the elegance of Haskell. To put it simply: stuff just works like you'd expect it to.<br />
<br />
To highlight the elegance of Haskell we shall now take a look at a small example. We choose QuickSort because it's a simple algorithm that is actually useful. We will look at two versions - one written in C++, an imperative language, and one written in Haskell.<br />
Both versions use only the functionality available to the programmer without importing any extra modules (otherwise we could just call "sort" in each language's standard library and be done with it!). Thus, we use the standard sequence primitives of each language (a "list" in Haskell and an "array" in C++). Both versions must also be polymorphic (which is done "automatically" in Haskell, and with templates in C++). Both versions must use the same recursive algorithm.<br />
<br />
Please note that this is ''not'' intended as a definite comparison between the two languages. It's intended to show the elegance of Haskell, the C++ version is only included for comparison (and would be coded quite differently if you used the Standard Template Libraries, for example).<br />
<br />
template <typename T><br />
void qsort (T *result, T *list, int n)<br />
{<br />
if (n == 0) return;<br />
T *smallerList, *largerList;<br />
smallerList = new T[n];<br />
largerList = new T[n]; <br />
T pivot = list[0];<br />
int numSmaller=0, numLarger=0; <br />
for (int i = 1; i < n; i++)<br />
if (list[i] < pivot)<br />
smallerList[numSmaller++] = list[i];<br />
else <br />
largerList[numLarger++] = list[i];<br />
<br />
qsort(smallerList,smallerList,numSmaller); <br />
qsort(largerList,largerList,numLarger);<br />
<br />
int pos = 0; <br />
for ( int i = 0; i < numSmaller; i++)<br />
result[pos++] = smallerList[i];<br />
<br />
result[pos++] = pivot;<br />
<br />
for ( int i = 0; i < numLarger; i++)<br />
result[pos++] = largerList[i];<br />
<br />
delete [] smallerList;<br />
delete [] largerList;<br />
};<br />
<br />
We will not explain this code further, just note how complex and difficult it is to understand at a glance, largely due to the programmer having to deal with low-level details which have nothing to do with the task at hand.<br />
Now, let's take a look at a Haskell version of QuickSort, which might look a something like this.<br />
<br />
<haskell><br />
qsort [] = []<br />
qsort (x:xs) = qsort less ++ [x] ++ qsort more<br />
where less = filter (<x) xs<br />
more = filter (>=x) xs<br />
</haskell><br />
<br />
Let's dissect this code in detail, since it uses quite a lot of Haskell syntax that you might not be familiar with.<br />
The function is called qsort and takes a list as a parameter. We define a function in Haskell like so: funcname a b c = expr, where funcname is the name of the function, a, b, and, c are the parameters and expr is the expression to be evaluated (most often using the parameters). Functions are called by simply putting the function name first and then the parameter(s). Haskell doesn't use parenthesis for function application. Functions simply bind more tightly than anything else, so "f 5 * 2", for instance, would apply f to 5 and then multiply by 2, if we wanted the multiplication to occur before the function application then we would use parenthesis like so "f (5*2)".<br />
<br />
Let's get back to QuickSort.<br />
First we see that we have two definitions of the functions. This is called pattern matching and we can briefly say that it will test the argument passed to the function top-to-bottom and use the first one that matches.<br />
The first definition matches against [] which in Haskell is the empty list (a list of 1,2 and 3 is [1,2,3] so it makes sense that an empty list is just two brackets).<br />
So when we try to sort an empty list, the result will be an empty list. Sounds reasonable enough, doesn't it?<br />
The second definition pattern matches against a list with at least one element. It does this by using (x:xs) for its argument. The "cons" operator is (:) and it simply puts an element in front of a list, so that 0 : [1,2,3] returns [0,1,2,3]. Pattern matching against (x:xs) is a match against the list with the head x and the tail xs (which may or may not be the empty list). In other words, (x:xs) is a list of at least one element.<br />
So since we will need to use the head of the list later, we can actually extract this very elegantly by using pattern matching. You can think of it as naming the contents of the list. This can be done on any data construct, not just a list. It is possible to pattern match against an arbitrary variable name and then use the head function on that to retrieve the head of the list.<br />
Now if we have a non empty list, the sorted list is produced by sorting all elements that are smaller than x and putting that in front of x, then we sort all elements larger than x and put those at the end. We do this by using the list concatenation operator ++. Notice that x is not a list so the ++ operator won't work on it alone, which is why we make it a singleton-list by putting it inside brackets.<br />
So the function reads "To sort the list, sandwich the head between the sorted list of all elements smaller than the head, and the sorted list of all elements larger than the head". Which could very well be the original algorithm description. This is very common in Haskell. A function definition usually resembles the informal description of the function very closely. This is why I say that Haskell has a smaller semantic gap than other languages.<br />
<br />
But wait, we're not done yet! How is the list less and more computed? Well, remember that we don't care about sequencing in Haskell, so we've defined them below the function using the where notation (which allows any definitions to use the parameters of the function to which they belong). We use the standard prelude function filter, I won't elaborate too much on this now, but the line less = filter (<x) xs will use filter (<x) xs to filter the list xs. You can see that we actually pass the function which will be used to filter the list to filter, an example of higher order functions.<br />
The function (<x) should be read out "the function 'less than x'" and will return True if an element passed to it is less than x (notice how easy it was to construct a function on the fly, we put the expression "<x", "less than x", in parenthesis and sent it off to the function - functions really are just another value!).<br />
All elements that pass the test are output from the filter function and put inside less. In a same way (>=x) is used to filter the list for all elements larger than or equal to x.<br />
<br />
Now that you've had the syntax explained to you, read the function definition again. Notice how little time it takes to get an understanding about what the function does. The function definitions in Haskell explain what it computes, not how.<br />
<br />
If you've already forgotten the syntax outlined above, don't worry! We'll go through it more thoroughly and at a slower pace in the tutorials. The important thing to get from this code example is that Haskell code is elegant and intuitive.<br />
<br />
===Haskell and bugs===<br />
We have several times stated that various features of Haskell help fight the occurrence of bugs. Let's recap these.<br />
<br />
Haskell programs have less bugs because Haskell is:<br />
<br />
* '''Pure'''. There are no side effects.<br />
<br />
* '''Strongly typed'''. There can be no dubious use of types. And No Core Dumps!<br />
<br />
* '''Concise'''. Programs are shorter which make it easier to look at a function and "take it all in" at once, convincing yourself that it's correct.<br />
<br />
* '''High level'''. Haskell programs most often reads out almost exactly like the algorithm description. Which makes it easier to verify that the function does what the algorithm states. By coding at a higher level of abstraction, leaving the details to the compiler, there is less room for bugs to sneak in.<br />
<br />
* '''Memory managed'''. There's no worrying about dangling pointers, the Garbage Collector takes care of all that. The programmer can worry about implementing the algorithm, not book-keeping of the memory.<br />
<br />
* '''Modular'''. Haskell offers stronger and more "glue" to compose your program from already developed modules. Thus Haskell programs can be more modular. Often used modular functions can thus be proven correct by induction. Combining two functions that are proven to be correct, will also give the correct result (assuming the combination is correct).<br />
<br />
Furthermore most people agree that you just think differently when solving problems in a functional language. You subdivide the problem into smaller and smaller functions and then you write these small (and "almost-guaranteed-to-be-correct") functions, which are composed in various ways to the final result. There just isn't any room for bugs!<br />
<br />
<br />
== Haskell vs OOP ==<br />
The great benefit of Object Oriented Programming is rarely that you group your data with the functions that act upon it together into an object - it's that it allows for great data encapsulation (separating the interface from implementation) and polymorphism (letting a whole set of data types behave the same way). However:<br />
<br />
''Data encapsulation and polymorphism are not exclusive to OOP!''<br />
<br />
Haskell has tools for abstracting data. We can't really get into it without first going through the module system and how abstract data types (ADT) work in Haskell, something which is well beyond the scope of this essay. We will therefore settle for a short description of how ADTs and polymorphism works in Haskell.<br />
<br />
Data encapsulation is done in Haskell by declaring each data type in a separate module, from this module you only export the interface. Internally there might be a host of functions that touch the actual data, but the interface is all that's visible from outside of the module.<br />
Note that the data type and the functions that act upon the data type are not grouped into an "object", but they are (typically) grouped into the same module, so you can choose to only export certain functions (and not the constructors for the data type) thus making these functions the only way to manipulate the data type - "hiding" the implementation from the interface.<br />
<br />
Polymorphism is done by using something called type classes. Now, if you come from a C++ or Java background you might associate classes with something resembling a template for how to construct an object, but that's not what they mean in Haskell. A type class in Haskell is really just what it sounds like. It's a set of rules for determining whether a type is an instance of that class.<br />
So Haskell separates the class instantiation and the construction of the data type. You might declare a type "Porsche", to be an instance of the "Car" type class, say. All functions that can be applied onto any other member of the Car type class can then be applied to a Porsche as well.<br />
A class that's included with Haskell is the Show type class, for which a type can be instantiated by providing a show function, which converts the data type to a String. Consequently almost all types in Haskell can be printed onto the screen by applying show on them to convert them to a String, and then using the relevant IO action (more on IO in the tutorials).<br />
Note how similar this is to the the object notion in OOP when it comes to the polymorphism aspect.<br />
The Haskell system is a more intuitive system for handling polymorphism. You won't have to worry about inheriting in the correct hierarchical order or to make sure that the inheritance is even sensible. A class is just a class, and types that are instances of this class really doesn't have to share some parent-child inheritance relationship. If your data type fulfills the requirements of a class, then it can be instantiated in that class. Simple, isn't it?<br />
Remember the QuickSort example? Remember that I said it was polymorphic? The secret behind the polymorphism in qsort is that it is defined to work on any type in the Ord type class (for "Ordered"). Ord has a set of functions defined, among them is "<" and ">=" which are sufficient for our needs because we only need to know whether an element is smaller than x or not. So if we were to define the Ord functions for our Porsche type (it's sufficient to implement, say, <= and ==, Haskell will figure out the rest from those) in an instantiation of the Ord type class, we could then use qsort to sort lists of Porsches (even though sorting Porsches might not make sense).<br />
Note that we never say anything about which classes the elements of the list must be defined for, Haskell will infer this automatically from just looking at which functions we have used (in the qsort example, only "<" and ">=" are relevant).<br />
<br />
So to summarize: Haskell does include mechanisms for data encapsulation that match or surpass those of OOP languages. The only thing Haskell does not provide is a way to group functions and data together into a single "object" (aside from creating a data type which includes a function - remember, functions are data!). This is, however, a very minor problem. To apply a function to an object you would write "func obj a b c" instead of something like "obj.func a b c".<br />
<br />
<br />
== Modularity ==<br />
A central concept in computing is modularity. A popular analogy is this: say you wanted to construct a wooden chair. If you construct the parts of it separately, and then glue them together, the task is solved easily. But if you were to carve the whole thing out of a solid piece of wood, it would prove to be quite a bit harder. John Hughes had this to say on the topic in his paper [http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters]<br />
<br />
''"Languages which aim to improve productivity must support modular programming well. But new scope rules and mechanisms for separate compilation are not enough - modularity means more than modules. Our ability to decompose a problem into parts depends directly on our ability to glue solutions together. To assist modular programming, a language must provide good glue.''<br />
<br />
''Functional programming languages provide two new kinds of glue - higher-order functions and lazy evaluation."''<br />
<br />
<br />
==The speed of Haskell ==<br />
Let me first state clearly that the following only applies to the general case in which speed isn't absolutely critical, where you can accept a few percent longer execution time for the benefit of reducing development time greatly. There are cases when speed is the primary concern, and then the following section will not apply to the same extent.<br />
<br />
Now, some C++ programmers might claim that the C++ version of QuickSort above is probably a bit faster than the Haskell version. And this might be true. For most applications, though, the difference in speed is so small that it's utterly irrelevant. For instance, take a look at the [http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=all Computer Language Shootout], where Haskell compares favorably to most of the so called "fast" languages.<br />
Now, these benchmarks don't prove all that much about real-world performance, but they do show that Haskell isn't as slow as some people think. At the time of writing it's in 4th position, only slightly behind C and C++.<br />
<br />
Almost all programs in use today have a fairly even spread of processing time among its functions. The most notable exceptions are applications like MPEG encoders, and artificial benchmarks, which spend a large portion of their execution time within a small portion of the code. If you ''really'' need speed at all costs, consider using C instead of Haskell.<br />
<br />
There's an old rule in computer programming called the "80/20 rule". It states that 80% of the time is spent in 20% of the code. The consequence of this is that any given function in your system will likely be of minimal importance when it comes to optimizations for speed. There may be only a handful of functions important enough to optimize. These important functions could be written in C (using the excellent foreign function interface in Haskell). The role of C could, and probably will, take over the role of assembler programming - you use it for the really time-critical bits of your system, but not for the whole system itself.<br />
<br />
We should continue to move to higher levels of abstraction, just like we've done before. We should trade application speed for increased productivity, stability and maintainability. Programmer time is almost always more expensive than CPU time.<br />
We aren't writing applications in assembler anymore for the same reason we shouldn't be writing applications in C anymore.<br />
<br />
Finally remember that algorithmic optimization can give much better results than code optimization. For theoretical examples when factors such as development times and stability doesn't matter, then sure C is often faster than Haskell. But in the real world development times ''do'' matter, this isn't the case. If you can develop your Haskell application in one tenth the time it would take to develop it in C (from experience, this is not at all uncommon) you will have lots of time to profile and implement new algorithims. So in the "real world" where we don't have infinite amounts of time to program our applications, Haskell programs can often be much faster than C programs.<br />
<br />
<br />
== Epilogue ==<br />
So if Haskell is so great, how come it isn't "mainstream"? Well, one reason is that the operating system is probably written in C or some other imperative language, so if your application mainly interacts with the internals of the OS, you may have an easier time using imperative languages. Another reason for the lack of Haskell, and other functional languages, in mainstream use is that programming languages are rarely thought of as tools (even though they are). To most people their favorite programming language is much more like religion - it just seems unlikely that any other language exists that can get the job done better and faster.<br />
<br />
There is a essay by Paul Graham called [http://www.paulgraham.com/avg.html Beating the Averages] describing his experience using Common Lisp, another functional language, for an upstart company. In it he uses an analogy which he calls "The Blub Paradox".<br />
<br />
It goes a little something like this:<br />
If a programmer's favorite language is Blub, which is positioned somewhere in the middle of the "power spectrum", he can most often only identify languages that are lower down in the spectrum. He can look at COBOL and say "How can anyone get anything done in that language, it doesn't have feature x", x being a feature in Blub.<br />
<br />
However, this Blub programmer has a harder time looking the other way in the spectrum. If he examines languages that are higher up in the power spectrum, they will just seem "weird" because the Blub programmer is "thinking in Blub" and can not possibly see the uses for various features of more powerful languages. It goes without saying that this inductively leads to the conclusion that to be able to compare all languages you'll need to position yourself at the top of the power spectrum. It is my belief that functional languages, almost by definition, are closer to the top of the power spectrum than imperative ones.<br />
So languages can actually limit a programmers frame of thought. If all you've ever programmed is Blub, you may not see the limitations of Blub - you may only do that by switching to another level which is more powerful.<br />
<br />
One of the reasons the mainstream doesn't use Haskell is because people feel that "their" language does "everything they need". And of course it does, because they are thinking in Blub! Languages aren't just technology, it's a way of thinking. And if you're not thinking in Haskell, it is very hard to see the use of Haskell - even if Haskell would allow you to write better applications in a shorter amount of time!<br />
<br />
Hopefully this article has helped you break out of the Blub paradox. Even though you may not yet "think in Haskell", it is my hope that you are at least aware of any limitations in your frame of thought imposed by your current "favorite" language, and that you now have more motivation to expand it by learning something new.<br />
<br />
If you are committed to learn a functional language, to get a better view of the power spectrum, then Haskell is an excellent candidate.<br />
<br />
[[Category:Tutorials]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=GHC/Type_families&diff=24157
GHC/Type families
2008-11-19T19:10:39Z
<p>CaleGibbard: </p>
<hr />
<div>[[Category:GHC|Indexed types]]<br />
== Type families in GHC ==<br />
<br />
Indexed type families are a new GHC extension to facilitate type-level programming. Type families are a generalisation of [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html associated data types] and [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html associated type synonyms], and are described in a [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html recent ICFP paper]. They essentially provide type-indexed data types and named functions on types, which are useful for generic programming and highly parameterised library interfaces as well as interfaces with enhanced static information, much like dependent types. They might also be regarded as an alternative to functional dependencies, but provide a more functional style of type-level programming than the relational style of functional dependencies.<br />
<br />
== What do I need to use type families? ==<br />
<br />
The first stable release of GHC that properly supports type families is 6.10.1. (An early partial implementation was part of the 6.8 release, but its use is deprecated.) Please [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&group=priority&type=bug&order=id&desc=1 report bugs] via the GHC bug tracker, ideally accompanied by a small example program that demonstrates the problem. Use the [mailto:glasgow-haskell-users@haskell.org GHC mailing list] for questions or for a discussion of this language extension and its description on this wiki page.<br />
<br />
== What are type families? ==<br />
<br />
Indexed type families, or type families for short, are type constructors that represent ''sets of types.'' Set members are denoted by supplying the type family constructor with type parameters, which are called ''type indices''. The difference between vanilla parametrised type constructors and family constructors is much like between parametrically polymorphic functions and (ad-hoc polymorphic) methods of type classes. Parametric polymorphic functions behave the same at all type instances, whereas class methods can change their behaviour in dependence on the class type parameters. Similarly, vanilla type constructors imply the same data representation for all type instances, but family constructors can have varying representation types for varying type indices.<br />
<br />
Indexed type families come in two flavours: ''data families'' and ''type synonym families''. They are the indexed family variants of algebraic data types and type synonyms, respectively. The instances of data families can be data types and newtypes.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analog to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.Map</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.Map.Map Int v)<br />
empty = GMapInt Data.Map.empty<br />
lookup k (GMapInt m) = Data.Map.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.Map.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundamental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Next, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and querying a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <hask>GMap</hask>] from GHC's test suite.<br />
<br />
== Detailed definition of data families ==<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indexes. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrived example is admissible:<br />
<haskell><br />
class C a b c where<br />
data T c a :: *<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed in type parameters, and type synonyms are allowed as long as they are fully applied and expand to a type that is itself admissible - exactly as this is required for occurrences of type synonyms in class instance parameters. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although, all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsense :: T a -> Int<br />
nonsense A = 1 -- WRONG: These two equations together...<br />
nonsense B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families are - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is the first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Scoping of class parameters ====<br />
<br />
In the case of multi-parameter type classes, the visibility of class parameters in the right-hand side of associated family instances depends ''solely'' on the parameters of the data family. As an example, consider the simple class declaration<br />
<haskell><br />
class C a b where<br />
data T a<br />
</haskell><br />
Only one of the two class parameters is a parameter to the data family. Hence, the following instance declaration is invalid:<br />
<haskell><br />
instance C [c] d where<br />
data T [c] = MkT (c, d) -- WRONG!! 'd' is not in scope<br />
</haskell><br />
Here, the right-hand side of the data instance mentions the type variable <hask>d</hask> that does not occur in its left-hand side. We cannot admit such data instances as they would compromise type safety.<br />
<br />
==== Type class instances of family instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implicitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This is for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapUnit</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== An associated type synonym example ==<br />
<br />
Type synonym families are an alternative to functional dependencies, which makes functional dependency examples well suited to introduce type synonym families. In fact, type families are a more functional way to express the same as functional dependencies (despite the name!), as they replace the relational notation of functional dependencies by an expression-oriented notation; i.e., functions on types are really represented by functions and not relations.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from Mark Jones' seminal paper on functional dependencies:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
Instead of the multi-parameter type class, we use a single parameter class, and the parameter <hask>e</hask><br />
turned into an associated type synonym <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Instances change in correspondingly. An instance of the two-parameter class<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
become an instance of a single-parameter class, where the dependant type parameter turns into an associated type instance declaration:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1, Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
== Detailed definition of type synonym families ==<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indexes to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Parameters can also be given explicit kind signatures if needed. We call the number of parameters in a type family declaration, the family's arity, and all applications of a type family must be fully saturated w.r.t. to that arity. This requirement is unlike ordinary type synonyms and it implies that the kind of a type family is not sufficient to determine a family's arity, and hence in general, also insufficient to determine whether a type family application is well formed. As an example, consider the following declaration:<br />
<haskell><br />
type family F a b :: * -> * -- F's arity is 2, <br />
-- although it's overall kind is * -> * -> * -> *<br />
</haskell><br />
Given this declaration the following are examples of well-formed and malformed types:<br />
<haskell><br />
F Char [Int] -- OK! Kind: * -> *<br />
F Char [Int] Bool -- OK! Kind: *<br />
F IO Bool -- WRONG: kind mismatch in the first argument<br />
F Bool -- WRONG: unsaturated application<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
The argument names of the type family must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. Hence, the following contrived example is admissible:<br />
<haskell><br />
class C a b c where<br />
type T c a :: *<br />
</haskell><br />
These rules are exactly as for associated data families.<br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed, and type synonyms are allowed as long as they are fully applied and expand to a type that is admissible - these are the exact same requirements as for data instances. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
Type family instance declarations are only legitimate when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration, and the number of type parameters in an instance declaration must match the number of type parameters in the family declaration. Finally, the right-hand side of a type instance must be a monotype (i.e., it may not include foralls) and after the expansion of all saturated vanilla type synonyms, no synonyms, except family synonyms may remain. Here are some examples of admissible and illegal type instances:<br />
<haskell><br />
type family F a :: *<br />
type instance F [Int] = Int -- OK!<br />
type instance F String = Char -- OK!<br />
type instance F (F a) = a -- WRONG: type parameter mentions a type family<br />
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter<br />
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type<br />
<br />
type family G a b :: * -> *<br />
type instance G Int = (,) -- WRONG: must be two type parameters<br />
type instance G Int Char Float = Double -- WRONG: must be two type parameters<br />
</haskell><br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instances declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a type family used in a single program may only overlap if the right-hand sides of the overlapping instances coincide for the overlapping types. More formally, two instance declarations overlap if there is a substitution that makes the left-hand sides of the instances syntactically the same. Whenever that is the case, the right-hand sides of the instances must also be syntactically equal under the same substitution. This condition is independent of whether the type family is associated or not, and it is not only a matter of consistency, but one of type safety.<br />
<br />
Here are two example to illustrate the condition under which overlap is permitted.<br />
<haskell><br />
type instance F (a, Int) = [a]<br />
type instance F (Int, b) = [b] -- overlap permitted<br />
<br />
type instance G (a, Int) = [a]<br />
type instance G (Char, a) = [a] -- ILLEGAL overlap, as [Char] /= [Int]<br />
</haskell><br />
<br />
==== Decidability ====<br />
<br />
In order to guarantee that type inference in the presence of type families decidable, we need to place a number of additional restrictions on the formation of type instance declarations (c.f., Definition 5 (Relaxed Conditions) of [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking with Open Type Functions]). Instance declarations have the general form<br />
<haskell><br />
type instance F t1 .. tn = t<br />
</haskell><br />
where we require that for every type family application <hask>(G s1 .. sm)</hask> in <hask>t</hask>, <br />
# <hask>s1 .. sm</hask> do not contain any type family constructors,<br />
# the total number of symbols (data type constructors and type variables) in <hask>s1 .. sm</hask> is strictly smaller than in <hask>t1 .. tn</hask>, and<br />
# for every type variable <hask>a</hask>, <hask>a</hask> occurs in <hask>s1 .. sm</hask> at most as often as in <hask>t1 .. tn</hask>.<br />
These restrictions are easily verified and ensure termination of type inference. However, they are not sufficient to guarantee completeness of type inference in the presence of, so called, ''loopy equalities'', such as <hask>a ~ [F a]</hask>, where a recursive occurrence of a type variable is underneath a family application and data constructor application - see the above mentioned paper for details. <br />
<br />
If the option <tt>-XUndecidableInstances</tt> is passed to the compiler, the above restrictions are not enforced and it is on the programmer to ensure termination of the normalisation of type families during type inference.<br />
<br />
=== Equality constraints ===<br />
<br />
Type context can include equality constraints of the form <hask>t1 ~ t2</hask>, which denote that the types <hask>t1</hask> and <hask>t2</hask> need to be the same. In the presence of type families, whether two types are equal cannot generally be decided locally. Hence, the contexts of function signatures may include equality constraints, as in the following example:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
</haskell><br />
where we require that the element type of <hask>c1</hask> and <hask>c2</hask> are the same. In general, the types <hask>t1</hask> and <hask>t2</hask> of an equality constraint may be arbitrary monotypes; i.e., they may not contain any quantifiers, independent of whether higher-rank types are otherwise enabled.<br />
<br />
Equality constraints can also appear in class and instance contexts. The former enable a simple translation of programs using functional dependencies into programs using family synonyms instead. The general idea is to rewrite a class declaration of the form<br />
<haskell><br />
class C a b | a -> b<br />
</haskell><br />
to<br />
<haskell><br />
class (F a ~ b) => C a b where<br />
type F a<br />
</haskell><br />
That is, we represent every functional dependency (FD) <hask>a1 .. an -> b</hask> by an FD type family <hask>F a1 .. an</hask> and a superclass context equality <hask>F a1 .. an ~ b</hask>, essentially giving a name to the functional dependency. In class instances, we define the type instances of FD families in accordance with the class head. Method signatures are not affected by that process.<br />
<br />
NB: Equalities in superclass contexts are not fully implemented in the GHC 6.10 branch.<br />
<br />
== References ==<br />
<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html Associated Types with Class.] Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In ''Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)'', pages 1-13, ACM Press, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms.] Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In ''Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 241-253, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SCPD07.html System F with Type Equality Coercions.] Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. In ''Proceedings of The Third ACM SIGPLAN Workshop on Types in Language Design and Implementation'', ACM Press, 2007.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking With Open Type Functions.] Tom Schrijvers, Simon Peyton-Jones, Manuel M. T. Chakravarty, Martin Sulzmann. In ''Proceedings of The 13th ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 51-62, 2008.<br />
<br />
[[Category:Type-level programming]]<br />
[[Category:Language extension]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Video_presentations&diff=22872
Video presentations
2008-09-12T18:46:46Z
<p>CaleGibbard: </p>
<hr />
<div>[[Category:Tutorials]]<br />
Collected videos of Haskell tutorials and conference presentations, sorted by topic.<br />
<br />
== Introductions to Haskell ==<br />
;<br />
http://panther2.video.blip.tv/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartI551-440.jpg<br />
A Taste of Haskell<br />
:[http://blip.tv/file/324976 Part 1] ([http://blip.tv/file/get/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartI455.flv Download])<br />
:[http://blip.tv/file/325646 Part 2] ([http://blip.tv/file/get/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartII749.flv Download])<br />
:[http://conferences.oreillynet.com/presentations/os2007/os_peytonjones.pdf Slides]<br />
:Simon Peyton-Jones, OSCON, July 2007.<br />
<blockquote><br />
Haskell is the world's leading purely functional programming language<br />
that offers a radical and elegant attack on the whole business of<br />
writing programs. In the last two or three years there has been an<br />
explosion of interest in Haskell, and it is now being used for a<br />
bewildering variety of applications. In this tutorial, I will try to<br />
show you why programming in Haskell is such fun, and how it makes you<br />
think about programming in a new way.<br />
</blockquote><br />
<br />
[http://channel9.msdn.com/showpost.aspx?postid=326762 Programming language nirvana]<br />
:Simon Peyton-Jones, Eric Meijer, MSR, July 2007.<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/peyton-jones-taming-effects-the-next-big-challenge/ Taming Effects - The Next Big Challenge]<br />
:Simon Peyton-Jones at Ericsson, February 2008.<br />
<br />
;[http://video.google.com/videoplay?docid=-4167170843018186532 Faith, Evolution, and Programming Languages]<br />
:Phil Wadler, April 2007. Slides are [http://homepages.inf.ed.ac.uk/wadler/topics/gj.html#oopsla here]<br />
<br />
;[http://port25.technet.com/archive/2007/09/26/haskell-in-the-hallway-sam-interviews-simon-peyton-jones.aspx Haskell in the Hallway]<br />
: An interview with SPJ at OSCON, Sep 2007.<br />
<br />
;[http://video.s-inf.de/#FP.2005-SS-Giesl.(COt).HD_Videoaufzeichnung Lecture Functional Programming]<br />
: A computer science lecture at RWTH University Aachen (Germany) dealing with functional programming and haskell (including theoretical background)<br />
<br />
;[http://www.dotnetrocks.com/default.aspx?ShowNum=310 Simon Peyton Jones on Functional Programming and Haskell (Audio)]<br />
:Simon explains laziness, purity, parallelism, side effects, monads, software transactional memory<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/john-launchbury-high-assurance-software/ High-Assurance Software] <br />
:John Launchbury at Ericsson, 21 February 2008.<br />
<br />
== ICFP 2007 and Workshops ==<br />
<br />
; [http://video.google.com/videoplay?docid=-1518197558546337776 The Reduceron: Widening the von Neumann Bottleneck for Graph Reduction using an FPGA.]<br />
:The Reduceron: Widening the von Neumann Bottleneck for Graph Reduction using an FPGA. A research talk given at IFL'2007 in Freiburg. Work by Matthew Naylor and Colin Runciman of the University of York. <br />
<br />
; [http://www.ludd.ltu.se/~pj/icfp2007/ICFP2007.html Selected videos from IFL 2007 and ICFP 2007.]<br />
<br />
; [http://www.ludd.ltu.se/~pj/hw2007/HaskellWorkshop.html All talks from Haskell Workshop 2007.]<br />
<br />
== Advanced topics in functional programming ==<br />
<br />
;[http://www.foomongers.org.uk/videos/spj-typedriventestinginhaskell.html Type-driven testing in Haskell]<br />
:Simon Peyton Jones talks about QuickCheck and SmallCheck<br />
<br />
;[http://www.youtube.com/user/TheCatsters The Catsters on YouTube]<br />
:Various interesting lectures on category theory, including monads, adjunctions, limits, and a variety of other topics.<br />
<br />
;[http://iba-cg.de/haskell.html Generic Programming in Haskell].<br />
:Johan Jeuring, July 2007.<br />
<br />
;[http://video.google.com/videoplay?docid=-4851250372422374791 Parametric Polymorphism and the Girard-Reynolds Isomorphism]<br />
:Phil Gossett, April 2007.<br />
<br />
;[http://channel9.msdn.com/ShowPost.aspx?PostID=358968#358968 Don't fear the monads]<br />
:Brian Beckman introducing monads<br />
<br />
== Concurrency and parallelism ==<br />
<br />
;[http://www.bayfp.org/blog/2008/05/17/video-and-slides-from-bryan-o%E2%80%99sullivans-talk/ Concurrent and multicore programming in Haskell]<br />
:[http://www.serpentine.com/blog/ Bryan O’Sullivan] at [http://bayfp.org Bay Area Functional Programmers], 8 May 2008<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/satnam-singh-declarative-programming-techniques-for-many-core-architectures/ Declarative Programming Techniques for Many-Core Architectures] <br />
:Satnam Singh at Ericsson, 21 February 2008<br />
<br />
;[http://www.blip.tv/file/317758/ Transactional Memory for Concurrent Programming]<br />
:Simon Peyton-Jones, OSCON, July 2007.<br />
<br />
;[http://channel9.msdn.com/Showpost.aspx?postid=231495 Programming in the Age of Concurrency: Software Transactional Memory]<br />
:Simon Peyton-Jones and Tim Harris, September 2006.<br />
<br />
;[http://www.londonhug.net/2007/09/25/nested-data-parallelism-video-returns/ Nested Data Parallelism in Haskell]<br />
:Simon Peyton-Jones, [http://www.londonhug.net/ London HUG], May 2007.<br />
:[http://research.microsoft.com/~simonpj/papers/ndp/NdpSlides.pdf Slides] (pdf)<br />
<br />
== The Web ==<br />
<br />
;[http://www.bayfp.org/blog/2007/10/16/alex-jacobson-on-happs-videos-slides/ HAppS]<br />
:Alex Jacobson, [http://www.bayfp.org/blog Bay Area FPers], Oct 2007.<br />
<br />
== Games ==<br />
<br />
;[http://www.londonhug.net/2007/09/24/better-video-for-games-in-haskell/ Games in Haskell]<br />
:2007 meeting of the London Haskell User Group. Matthew Sackman and Tristan Allwood of Imperial College talk about building 3D games in Haskell.<br />
<br />
;[http://uk.youtube.com/watch?v=uziCn2SBbxs Data parallel physics engine]<br />
:2008, Hpysics' visulization code now performs double buffering<br />
<br />
;[http://uk.youtube.com/watch?v=mwge13bX9W8 Yampa Space Invaders]<br />
:Space Invaders, using functional reactive programming.<br />
<br />
;[http://uk.youtube.com/watch?v=zqFgQiPKtOI Monadius]<br />
:A 2D space game<br />
<br />
== The ICFP contest ==<br />
<br />
;[http://video.google.com/videoplay?docid=6419094369756184531 2006 ICFP contest results]<br />
:ICFP, 2006<br />
<br />
;[http://www.ludd.ltu.se/~pj/icfp2007/ICFP%20contest%202007.mov 2007 ICFP contest results]<br />
:ICFP, 2007<br />
<br />
== Livecoding Haskell ==<br />
<br />
[[Category:Music]]<br />
<br />
;[http://video.google.de/videoplay?docid=-6594267962912965757&q=hal2+july+2007&total=7&start=0&num=50&so=0&type=search&plindex=3 Music and Sound generation]<br />
:Henning Thielemann July 2007 in Leipzig about Music and Sound using SuperCollider, CSound, MIDI and pure Haskell (German)<br />
<br />
;[http://youtube.com/watch?v=xaoLbKWMwoU Haskell music]<br />
:[http://doc.gold.ac.uk/~ma503am/ Yaxu], 2006.<br />
<br />
;[http://youtube.com/watch?v=eLS6GHXWMpA Hacking Haskell music]<br />
:More of Yaxu live coding music and Haskell, 2006.<br />
<br />
;[http://doc.gold.ac.uk/~ma503am/alex/asciirave ASCII Rave in Haskell]<br />
:Yaxu, using words to control the articulation of a physical modelling synthesiser based on the elegant Karplus-Strong algorithm<br />
<br />
== GHC Hackathon presentations ==<br />
<br />
;[http://hackage.haskell.org/trac/ghc/wiki/AboutVideos GHC commentary]<br />
:Simon Peyton Jones and Simon Marlow, 2006.<br />
<br />
== Commercial users ==<br />
<br />
;[http://www.londonhug.net/2008/08/11/video-paradise-a-dsel-for-derivatives-pricing/ Paradise]<br />
:An EDSL in Haskell developed by Credit Suisse for Derivatives Pricing<br />
<br />
== Haskell applications ==<br />
<br />
;[http://www.youtube.com/watch?v=oYdkrOMhFWU Emacs Flymake]<br />
:Daisuke IKEGAMI, a demo of editing Haskell program on Emacs with on-the-fly syntax and type checking using flymake-mode (see also [http://www.emacswiki.org/cgi-bin/emacs/FlymakeHaskell EmacsWiki:FlymakeHaskell] for details), 11 November 2007<br />
<br />
;[http://video.google.de/videosearch?q=hal2+july+2007 HAL2]<br />
:HAL2 meeting in July 2007 in Leipzig, presenting talks about Generic Programming (English), Eclipse for Haskell (German), Grapefruit GUI (German) and Music+Sound generation (German)<br />
<br />
;[http://ftp.belnet.be/mirrors/FOSDEM/2006/FOSDEM2006-darcs.avi GADTs for darcs]<br />
:David Roundy, FOSDEM, 2006<br />
<br />
;[http://www.londonhug.net/2008/02/02/video-darcs-and-gadts/ Darcs and Generalised Algebraic Data Types]<br />
:Ganesh Sittampalamhs talk on Darcs and GADTs<br />
<br />
;[http://www.uwtv.org/programs/displayevent.aspx?rID=2124&fID=368 Functional Image Synthesis]<br />
:Conal Elliott, talk at University of Washington, November 2000<br />
<br />
;[http://www.youtube.com/watch?v=faJ8N0giqzw Tangible Functional Programming]<br />
:Conal Eliott's Google Tech Talk<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/john-hughes-testing-with-quickcheck/ Testing with QuickCheck]<br />
:John Hughes at Ericsson, 21 February 2008<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/simon-peyton-jones-composing-contracts-an-adventure-in-financial-engineering/ Composing Contracts - An Adventure in Financial Engineering] <br />
:Simon Peyton Jones at Ericsson, 21 February 2008.<br />
<br />
;[http://www.ludd.ltu.se/~pj/hw2007/xmonad.mov xmonad]<br />
: Don Stewart at the Haskell Workshop, 2007.<br />
<br />
;[http://www.youtube.com/watch?v=yHd0u6zuWdw Coconut: COde CONstructing User Tool]<br />
:Haskell DSL to produce high performance SIMD-Parallel code<br />
<br />
;[http://covector.blogspot.com/2007/10/functional-augmented-reality.html Augmented reality using Haskell computer vision]<br />
:Functional augmented reality, Alberto Ruiz<br />
<br />
== Other ==<br />
<br />
;[http://www.youtube.com/watch?v=faJ8N0giqzw Tangible Functional Programming: a modern marriage of usability and composability]<br />
:Conal Elliott. Google TechTalk, November 2007</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Video_presentations&diff=22871
Video presentations
2008-09-12T18:46:13Z
<p>CaleGibbard: </p>
<hr />
<div>[[Category:Tutorials]]<br />
Collected videos of Haskell tutorials and conference presentations, sorted by topic.<br />
<br />
== Introductions to Haskell ==<br />
;<br />
http://panther2.video.blip.tv/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartI551-440.jpg<br />
A Taste of Haskell<br />
:[http://blip.tv/file/324976 Part 1] ([http://blip.tv/file/get/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartI455.flv Download])<br />
:[http://blip.tv/file/325646 Part 2] ([http://blip.tv/file/get/OSCON-OSCON2007SimonPeytonJonesATasteOfHaskellPartII749.flv Download])<br />
:[http://conferences.oreillynet.com/presentations/os2007/os_peytonjones.pdf Slides]<br />
:Simon Peyton-Jones, OSCON, July 2007.<br />
<blockquote><br />
Haskell is the world's leading purely functional programming language<br />
that offers a radical and elegant attack on the whole business of<br />
writing programs. In the last two or three years there has been an<br />
explosion of interest in Haskell, and it is now being used for a<br />
bewildering variety of applications. In this tutorial, I will try to<br />
show you why programming in Haskell is such fun, and how it makes you<br />
think about programming in a new way.<br />
</blockquote><br />
<br />
[http://channel9.msdn.com/showpost.aspx?postid=326762 Programming language nirvana]<br />
:Simon Peyton-Jones, Eric Meijer, MSR, July 2007.<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/peyton-jones-taming-effects-the-next-big-challenge/ Taming Effects - The Next Big Challenge]<br />
:Simon Peyton-Jones at Ericsson, February 2008.<br />
<br />
;[http://video.google.com/videoplay?docid=-4167170843018186532 Faith, Evolution, and Programming Languages]<br />
:Phil Wadler, April 2007. Slides are [http://homepages.inf.ed.ac.uk/wadler/topics/gj.html#oopsla here]<br />
<br />
;[http://port25.technet.com/archive/2007/09/26/haskell-in-the-hallway-sam-interviews-simon-peyton-jones.aspx Haskell in the Hallway]<br />
: An interview with SPJ at OSCON, Sep 2007.<br />
<br />
;[http://video.s-inf.de/#FP.2005-SS-Giesl.(COt).HD_Videoaufzeichnung Lecture Functional Programming]<br />
: A computer science lecture at RWTH University Aachen (Germany) dealing with functional programming and haskell (including theoretical background)<br />
<br />
;[http://www.dotnetrocks.com/default.aspx?ShowNum=310 Simon Peyton Jones on Functional Programming and Haskell (Audio)]<br />
:Simon explains laziness, purity, parallelism, side effects, monads, software transactional memory<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/john-launchbury-high-assurance-software/ High-Assurance Software] <br />
:John Launchbury at Ericsson, 21 February 2008.<br />
<br />
== ICFP 2007 and Workshops ==<br />
<br />
; [http://video.google.com/videoplay?docid=-1518197558546337776 The Reduceron: Widening the von Neumann Bottleneck for Graph Reduction using an FPGA.]<br />
:The Reduceron: Widening the von Neumann Bottleneck for Graph Reduction using an FPGA. A research talk given at IFL'2007 in Freiburg. Work by Matthew Naylor and Colin Runciman of the University of York. <br />
<br />
; [http://www.ludd.ltu.se/~pj/icfp2007/ICFP2007.html Selected videos from IFL 2007 and ICFP 2007.]<br />
<br />
; [http://www.ludd.ltu.se/~pj/hw2007/HaskellWorkshop.html All talks from Haskell Workshop 2007.]<br />
<br />
== Advanced topics in functional programming ==<br />
<br />
;[http://www.foomongers.org.uk/videos/spj-typedriventestinginhaskell.html Type-driven testing in Haskell]<br />
:Simon Peyton Jones talks about QuickCheck and SmallCheck<br />
<br />
;[http://www.youtube.com/user/TheCatsters The Catsters on YouTube<br />
:Various interesting lectures on category theory, including monads, adjunctions, limits, and a variety of other topics.<br />
<br />
;[http://iba-cg.de/haskell.html Generic Programming in Haskell].<br />
:Johan Jeuring, July 2007.<br />
<br />
;[http://video.google.com/videoplay?docid=-4851250372422374791 Parametric Polymorphism and the Girard-Reynolds Isomorphism]<br />
:Phil Gossett, April 2007.<br />
<br />
;[http://channel9.msdn.com/ShowPost.aspx?PostID=358968#358968 Don't fear the monads]<br />
:Brian Beckman introducing monads<br />
<br />
== Concurrency and parallelism ==<br />
<br />
;[http://www.bayfp.org/blog/2008/05/17/video-and-slides-from-bryan-o%E2%80%99sullivans-talk/ Concurrent and multicore programming in Haskell]<br />
:[http://www.serpentine.com/blog/ Bryan O’Sullivan] at [http://bayfp.org Bay Area Functional Programmers], 8 May 2008<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/satnam-singh-declarative-programming-techniques-for-many-core-architectures/ Declarative Programming Techniques for Many-Core Architectures] <br />
:Satnam Singh at Ericsson, 21 February 2008<br />
<br />
;[http://www.blip.tv/file/317758/ Transactional Memory for Concurrent Programming]<br />
:Simon Peyton-Jones, OSCON, July 2007.<br />
<br />
;[http://channel9.msdn.com/Showpost.aspx?postid=231495 Programming in the Age of Concurrency: Software Transactional Memory]<br />
:Simon Peyton-Jones and Tim Harris, September 2006.<br />
<br />
;[http://www.londonhug.net/2007/09/25/nested-data-parallelism-video-returns/ Nested Data Parallelism in Haskell]<br />
:Simon Peyton-Jones, [http://www.londonhug.net/ London HUG], May 2007.<br />
:[http://research.microsoft.com/~simonpj/papers/ndp/NdpSlides.pdf Slides] (pdf)<br />
<br />
== The Web ==<br />
<br />
;[http://www.bayfp.org/blog/2007/10/16/alex-jacobson-on-happs-videos-slides/ HAppS]<br />
:Alex Jacobson, [http://www.bayfp.org/blog Bay Area FPers], Oct 2007.<br />
<br />
== Games ==<br />
<br />
;[http://www.londonhug.net/2007/09/24/better-video-for-games-in-haskell/ Games in Haskell]<br />
:2007 meeting of the London Haskell User Group. Matthew Sackman and Tristan Allwood of Imperial College talk about building 3D games in Haskell.<br />
<br />
;[http://uk.youtube.com/watch?v=uziCn2SBbxs Data parallel physics engine]<br />
:2008, Hpysics' visulization code now performs double buffering<br />
<br />
;[http://uk.youtube.com/watch?v=mwge13bX9W8 Yampa Space Invaders]<br />
:Space Invaders, using functional reactive programming.<br />
<br />
;[http://uk.youtube.com/watch?v=zqFgQiPKtOI Monadius]<br />
:A 2D space game<br />
<br />
== The ICFP contest ==<br />
<br />
;[http://video.google.com/videoplay?docid=6419094369756184531 2006 ICFP contest results]<br />
:ICFP, 2006<br />
<br />
;[http://www.ludd.ltu.se/~pj/icfp2007/ICFP%20contest%202007.mov 2007 ICFP contest results]<br />
:ICFP, 2007<br />
<br />
== Livecoding Haskell ==<br />
<br />
[[Category:Music]]<br />
<br />
;[http://video.google.de/videoplay?docid=-6594267962912965757&q=hal2+july+2007&total=7&start=0&num=50&so=0&type=search&plindex=3 Music and Sound generation]<br />
:Henning Thielemann July 2007 in Leipzig about Music and Sound using SuperCollider, CSound, MIDI and pure Haskell (German)<br />
<br />
;[http://youtube.com/watch?v=xaoLbKWMwoU Haskell music]<br />
:[http://doc.gold.ac.uk/~ma503am/ Yaxu], 2006.<br />
<br />
;[http://youtube.com/watch?v=eLS6GHXWMpA Hacking Haskell music]<br />
:More of Yaxu live coding music and Haskell, 2006.<br />
<br />
;[http://doc.gold.ac.uk/~ma503am/alex/asciirave ASCII Rave in Haskell]<br />
:Yaxu, using words to control the articulation of a physical modelling synthesiser based on the elegant Karplus-Strong algorithm<br />
<br />
== GHC Hackathon presentations ==<br />
<br />
;[http://hackage.haskell.org/trac/ghc/wiki/AboutVideos GHC commentary]<br />
:Simon Peyton Jones and Simon Marlow, 2006.<br />
<br />
== Commercial users ==<br />
<br />
;[http://www.londonhug.net/2008/08/11/video-paradise-a-dsel-for-derivatives-pricing/ Paradise]<br />
:An EDSL in Haskell developed by Credit Suisse for Derivatives Pricing<br />
<br />
== Haskell applications ==<br />
<br />
;[http://www.youtube.com/watch?v=oYdkrOMhFWU Emacs Flymake]<br />
:Daisuke IKEGAMI, a demo of editing Haskell program on Emacs with on-the-fly syntax and type checking using flymake-mode (see also [http://www.emacswiki.org/cgi-bin/emacs/FlymakeHaskell EmacsWiki:FlymakeHaskell] for details), 11 November 2007<br />
<br />
;[http://video.google.de/videosearch?q=hal2+july+2007 HAL2]<br />
:HAL2 meeting in July 2007 in Leipzig, presenting talks about Generic Programming (English), Eclipse for Haskell (German), Grapefruit GUI (German) and Music+Sound generation (German)<br />
<br />
;[http://ftp.belnet.be/mirrors/FOSDEM/2006/FOSDEM2006-darcs.avi GADTs for darcs]<br />
:David Roundy, FOSDEM, 2006<br />
<br />
;[http://www.londonhug.net/2008/02/02/video-darcs-and-gadts/ Darcs and Generalised Algebraic Data Types]<br />
:Ganesh Sittampalamhs talk on Darcs and GADTs<br />
<br />
;[http://www.uwtv.org/programs/displayevent.aspx?rID=2124&fID=368 Functional Image Synthesis]<br />
:Conal Elliott, talk at University of Washington, November 2000<br />
<br />
;[http://www.youtube.com/watch?v=faJ8N0giqzw Tangible Functional Programming]<br />
:Conal Eliott's Google Tech Talk<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/john-hughes-testing-with-quickcheck/ Testing with QuickCheck]<br />
:John Hughes at Ericsson, 21 February 2008<br />
<br />
;[http://ulf.wiger.net/weblog/2008/02/29/simon-peyton-jones-composing-contracts-an-adventure-in-financial-engineering/ Composing Contracts - An Adventure in Financial Engineering] <br />
:Simon Peyton Jones at Ericsson, 21 February 2008.<br />
<br />
;[http://www.ludd.ltu.se/~pj/hw2007/xmonad.mov xmonad]<br />
: Don Stewart at the Haskell Workshop, 2007.<br />
<br />
;[http://www.youtube.com/watch?v=yHd0u6zuWdw Coconut: COde CONstructing User Tool]<br />
:Haskell DSL to produce high performance SIMD-Parallel code<br />
<br />
;[http://covector.blogspot.com/2007/10/functional-augmented-reality.html Augmented reality using Haskell computer vision]<br />
:Functional augmented reality, Alberto Ruiz<br />
<br />
== Other ==<br />
<br />
;[http://www.youtube.com/watch?v=faJ8N0giqzw Tangible Functional Programming: a modern marriage of usability and composability]<br />
:Conal Elliott. Google TechTalk, November 2007</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Template:Main/Success&diff=22358
Template:Main/Success
2008-08-11T04:47:38Z
<p>CaleGibbard: </p>
<hr />
<div>'''Who's using Haskell?'''<br />
<br />
;[http://www.amgen.com/ Amgen]<br />
:uses Haskell to rapidly build software based on mathematical models<br />
;[http://www.microsoft.com/ Microsoft Research]<br />
:has ongoing research investments in Haskell<br />
;[http://www.eaton.com/ Eaton Corporation]<br />
:uses Haskell to control hybrid vehicles<br />
;[http://www.db.com/ Deutsche Bank]<br />
:employs Haskell for trading software<br />
;[http://antiope.com/ Antiope]<br />
:uses Haskell for simulation and verification of wireless systems<br />
<br />
More Haskell success stories at [http://cufp.galois.com/2008/main.html CUFP] and the [[Haskell_in_industry|Industry Wiki]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Monads_as_computation&diff=22285
Monads as computation
2008-08-07T20:34:03Z
<p>CaleGibbard: </p>
<hr />
<div>=== Motivation ===<br />
<br />
Programmers in general, and functional programmers in particular, are usually not so content to solve a problem in a fragile way by coding a solution directly. Quite often the best way to solve a problem is to design a domain-specific language in which the solution to one's problem is easily expressed. Doing this generally ensures that a wide class of similar problems can be attacked using the same code. That way, you get code which is resistant to damage in the form of changes to design requirements.<br />
<br />
Better still, we'd like to embed those domain specific languages into the language which we wrote them in, so that they can be used together, and so we get benefits from the language we're working in without so much extra work. So we write combinator libraries which are essentially libraries of code whose API's are sufficiently powerful that using the library is like programming in a small language embedded within the existing one.<br />
<br />
Such a library will have some representation of primitive computations, and some ways to glue those computations together into more complex ones. A parsing library might define primitive parsers for parsing single characters, and then combining functions for concatenating parsers or selecting between them. A drawing library might define some basic drawing operations, and then various means of combining drawings into larger ones (on top, beside, above, etc.).<br />
<br />
In this manner, the user of the combinator library builds up the computation they want, piecing together smaller parts into larger ones.<br />
<br />
As far as programming is concerned, a [[monad]] is just a particular style of combinator library. That is, one which supports a few basic means of combination.<br />
<br />
The reason for making this abstraction is so that all the libraries which make use of those means of combination can then share a library of combining functions built up from the primitive ones they are required to support.<br />
<br />
Specifically, by defining an instance of Monad for your library when appropriate, you automatically get the benefit of the functions in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad library] (as well as a few others, like [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html Data.Traversable]). This includes things like for-each loops (forM/mapM), ways to turn pure functions into combiners (liftM2, etc.), as well as other control structures which you get for free just for making your library an instance of Monad.<br />
<br />
=== The parts of a monad ===<br />
<br />
There are of course, other kinds of combinator library, but monads arise fairly naturally from a few basic premises.<br />
<br />
* Monadic computations have results. This is reflected in the types. Given a monad M, a value of type <code>M t</code> is a computation resulting in a value of type <code>t</code>. It's important to realise that this is typically just some data structure. It will be interpreted as a computation and "run" in a way which is dependent on the given library.<br />
* For any value, there is a computation which "does nothing", and produces that result. This is given by defining the function <code>return</code> for the given monad.<haskell><br />
return :: (Monad m) => a -> m a<br />
</haskell><br />
* Given a pair of computations <hask>x</hask> and <hask>y</hask>, one can form the computation <hask>x >> y</hask>, which intuitively "runs" the computation <hask>x</hask>, throws away its result, then runs <hask>y</hask> returning its result.<haskell><br />
(>>) :: (Monad m) => m a -> m b -> m b<br />
</haskell><br />
* Further, we're allowed to use the result of the first computation to decide "what to do next", rather than just throwing it away. This idea is embodied by the operation <hask>(>>=)</hask>, called 'bind'. If <hask>x</hask> is a computation, and <hask>f</hask> is a function from potential results of that computation to further computations to be performed, then <hask>x >>= f</hask> is a computation which runs <hask>x</hask>, then applies <hask>f</hask> to its result, getting a computation which it then runs. The result of this latter computation is the result of the combined one.<haskell><br />
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b<br />
</haskell><br />
<br />
In fact, once we have bind, we can always define <hask>(>>)</hask> as:<br />
<haskell><br />
x >> y = x >>= (\k -> y)<br />
</haskell><br />
<br />
It's important to realise that both what it means to "run" a computation, and what "then" means in the above are both <em>up to the monad in question</em> (subject to a few simple constraints to be discussed later). This point will become clearer as one sees more and more examples.<br />
<br />
=== A few examples ===<br />
<br />
On top of <hask>return</hask> and <hask>(>>=)</hask>, any given monad will typically define a bunch of primitive computations to get the user of the library started. The <hask>IO</hask> monad, for instance, has a large number of I/O operations such as <hask>getLine :: IO String</hask> and <hask>putStrLn :: String -> IO ()</hask>. The program: <haskell><br />
main :: IO ()<br />
main = getLine >>= putStrLn<br />
</haskell> gets a line of text from the user, and then prints it back out.<br />
For a slightly more complicated example, the program: <haskell><br />
main :: IO ()<br />
main = putStrLn "Enter a line of text:"<br />
>> getLine >>= \x -> putStrLn (reverse x)<br />
</haskell> prompts the user for a line of text, gets the line of text from the user, and then prints it back out in reverse.<br />
<br />
A parsing monad might define <hask>char :: Char -> Parser Char</hask>, for constructing a parser which succeeds if the input string matches the given character. As a very simple example without getting into the details of parsing monads, the parser: <haskell><br />
cat = char 'c' >> char 'a' >> char 't' >> return "It's a cat."<br />
</haskell> would try to match the string "cat", and if the parse succeeded, would return the string <hask>"It's a cat."</hask>.<br />
<br />
=== Do notation ===<br />
<br />
Because computations are typically going to be built up from long chains of <hask>(>>)</hask> and <hask>(>>=)</hask>, in Haskell, we have some syntax-sugar, called do-notation.<br />
<br />
The do-notation allows us to write our second IO program above as:<br />
<haskell><br />
main = do putStrLn "Enter a line of text:"<br />
x <- getLine<br />
putStrLn (reverse x)<br />
</haskell><br />
<br />
The basic mechanical translation for the do-notation is as follows:<br />
<haskell><br />
do { x } = x<br />
<br />
do { x ; <stmts> }<br />
= x >> do { <stmts> }<br />
<br />
do { v <- x ; <stmts> }<br />
= x >>= \v -> do { <stmts> }<br />
<br />
do { let <decls> ; <stmts> }<br />
= let <decls> in do { <stmts> }<br />
</haskell><br />
<br />
This gives monadic computations a bit of an imperative feel, but it's important to remember that the monad in question gets to decide what the combination means, and so some unusual forms of control flow might actually occur. In some monads (like parsers, or the list monad), "backtracking" may occur, and in others, even more exotic forms of control might show up (for instance, first-class continuations, or some form of parallelism).<br />
<br />
=== The monad laws ===<br />
<br />
However, in order to maintain some semblance of sanity, we agree to make the monads we define follow some basic rules. I'll show the three rules both in terms of <hask>return</hask> and <hask>(>>=)</hask> and do-notation, and try to give some feel of what they really mean.<br />
<br />
<haskell><br />
1. return v >>= f == f v<br />
<br />
2. x >>= return == x<br />
<br />
3. (x >>= f) >>= g == x >>= (\v -> f v >>= g)<br />
</haskell><br />
<br />
Rules 1 and 2 basically give one the sense that <hask>return v</hask> "does nothing" and results in <hask>v</hask>.<br />
<br />
Rule 3 puts a bit of a constraint on what "then" is supposed to mean. It is perhaps easier at first to look at what it means for <hask>(>>)</hask>:<br />
<haskell><br />
(x >> y) >> z == x >> (y >> z)<br />
</haskell><br />
This corresponds nicely with our usual reading of <hask>(>>)</hask> as "then":<br />
<br />
putting on your tie, <strong>then</strong> (putting on your socks <strong>then</strong> putting on your shoes)<br />
<br />
is the same thing as<br />
<br />
(putting on your tie <strong>then</strong> putting on your socks) <strong>then</strong> putting on your shoes.<br />
<br />
To get a bit of a different perspective on what the laws mean, let's see what they look like in do-notation:<br />
<br />
<haskell><br />
1. do { w <- return v; f w }<br />
== do { f v }<br />
<br />
2. do { v <- x; return v }<br />
== do { x }<br />
</haskell><br />
<br />
These two are again consistent with the idea that return produces a computation that has no "side-effects", and just returns its parameter.<br />
<br />
<haskell><br />
3. do w <- do v <- x<br />
f v<br />
g w<br />
<br />
== do v <- x<br />
w <- f v<br />
g w<br />
</haskell><br />
<br />
This is more interesting. It's telling us that asking for the result of a compound computation in the midst of a do-block will result in exactly the same thing as if that compound computation had been spliced in directly, and gives us a valid way to refactor code written in any monad. We're allowed to abstract a chunk of code out from the middle of a do-block and give it a name without worrying about whether we've changed the meaning of the code.<br />
<br />
=== The whole point ===<br />
<br />
This is all very good, but apart from defining a pretty syntax for a certain kind of combinator library, the stuff we've done so far is fairly inessential. What's the point of recognising something as a monad?<br />
<br />
The point, as I alluded to in the introduction, is that we can then write code which works for all monads, and have a whole library of code which is made available to us just for recognising that the library we're writing happens to be a monad. Since we have only return and bind to work with, this sort of code will serve to chain computations together in some methodical way. That is to say, it will consist of control structures.<br />
<br />
All the examples I'll give are already defined in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad] library, along with many more.<br />
<br />
The first example of such a control structure we'll look at is called <hask>sequence</hask>. It's a function which takes a list of computations of the same type, and builds from them a computation which will run each in turn and produce a list of the results:<br />
<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = do v <- x<br />
vs <- sequence xs<br />
return (v:vs)<br />
</haskell><br />
or, without the do-notation:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = x >>= \v -> sequence xs >>= \vs -> return (v:vs)<br />
</haskell><br />
(one can start to see why do-notation might be desirable!)<br />
<br />
In a parsing monad, we might pass it a list of parsers, and get back a parser which parses its input using each in turn. In the IO monad, a simple example might be the following:<br />
<haskell><br />
main = sequence [getLine, getLine] >>= print<br />
</haskell><br />
which gets two lines of text from the user, and then prints the list.<br />
<br />
Since lists are lazy in Haskell, this gives us a sort of primordial loop from which most other kinds of loops can be built.<br />
<br />
What is a for-each loop really? It's something which performs some action based on each element of a list. So we might imagine a function with the type:<br />
<haskell><br />
forM :: (Monad m) => [a] -> (a -> m b) -> m [b]<br />
</haskell><br />
(as an added bonus, we'll have it collect the results of each iteration).<br />
<br />
We can write this with sequence and map:<br />
<haskell><br />
forM xs f = sequence (map f xs)<br />
</haskell><br />
we apply the function to each element of the list to construct the action for that iteration, and then sequence the actions together into a single computation.<br />
<br />
For example:<br />
<haskell><br />
main = forM [1..10] $ \x -> do<br />
putStr "Looping: "<br />
print x<br />
</haskell><br />
<br />
Since in this, and many other cases, the loop body doesn't produce a particularly interesting result, there are variants of <hask>sequence</hask> and <hask>forM</hask> called <hask>sequence_</hask> and <hask>forM_</hask>, which simply throw the results away as they run each of the actions.<br />
<br />
<haskell><br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ [] = return ()<br />
sequence_ (x:xs) = x >> sequence xs<br />
<br />
forM_ :: (Monad m) => [a] -> (a -> m b) -> m ()<br />
forM_ xs f = sequence_ (map f xs)<br />
</haskell><br />
<br />
Sometimes we only want a computation to happen when a given condition is true. For this, we can write the following:<br />
<haskell><br />
when :: (Monad m) => Bool -> m () -> m ()<br />
when p x = if p then x else return ()<br />
</haskell><br />
Remember that <hask>return ()</hask> is a no-op, so running this computation will run x when the condition is true, and will do nothing at all when the condition fails.<br />
<br />
Another extremely common thing to do is to construct a computation which performs another computation and then applies a function to the result. This can be accomplished by using the <hask>liftM</hask> function:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = do v <- x<br />
return (f v)<br />
</haskell><br />
Or:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = return . f =<< x<br />
</haskell><br />
where <hask>(=<<)</hask> is just bind with its parameters flipped.<br />
<br />
This is also generalised by <hask>liftM2, liftM3, ...</hask> to running more than one computation before applying a function to the results:<br />
<haskell><br />
liftM2 :: (Monad m) => (a -> b -> c) -> m a -> m b -> m c<br />
liftM2 f x y = do v <- x<br />
w <- y<br />
return (f v w)<br />
</haskell><br />
<br />
It's possible to rewrite sequence in terms of liftM2, return, and a fold over the list:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence xs = foldr (liftM2 (:)) (return []) xs<br />
<br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ xs = foldr (>>) (return ()) xs<br />
</haskell><br />
<br />
Anyway, these are just a few of the simpler examples to give a taste of what sorts of control structures you get for free by defining a combinator library as a monad.<br />
<br />
=== Some final notes ===<br />
<br />
It's a common misconception that Haskell uses a monad for I/O out of necessity. Really, it could use any sort of combinator library to describe and combine I/O actions. It just happens that the most obvious way to formulate a library to describe I/O actions ends up being a monad. So we define it as such so as to be able to share all these control structures with other monadic libraries.<br />
<br />
That's really the only reason why we ever define anything as a monad -- the abstraction allows us to make use of a bunch of shared code for free without writing it out over and over again (or worse yet, failing to abstract it at all).<br />
<br />
At this point, you might want to look at some more examples of monads. One place which is a decent starting point for that is [http://www.haskell.org/all_about_monads/html/introII.html Part II of the "All About Monads" tutorial]. You might also have a look at the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Hierarchical Libraries Documentation] for the libraries under Control.Monad.<br />
<br />
-- [[User:CaleGibbard|CaleGibbard]]<br />
<br />
[[Category:Tutorials]] [[Category:Monad]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Monads_as_computation&diff=22283
Monads as computation
2008-08-07T19:35:47Z
<p>CaleGibbard: </p>
<hr />
<div>=== Motivation ===<br />
<br />
Programmers in general, and functional programmers in particular, are usually not so content to solve a problem in a fragile way by coding a solution directly. Quite often the best way to solve a problem is to design a domain-specific language in which the solution to one's problem is easily expressed. Doing this generally ensures that a wide class of similar problems can be attacked using the same code. That way, you get code which is resistant to damage in the form of changes to design requirements.<br />
<br />
Better still, we'd like to embed those domain specific languages into the language which we wrote them in, so that they can be used together, and so we get benefits from the language we're working in without so much extra work. So we write combinator libraries which are essentially libraries of code whose API's are sufficiently powerful that using the library is like programming in a small language embedded within the existing one.<br />
<br />
Such a library will have some representation of primitive computations, and some ways to glue those computations together into more complex ones. A parsing library might define primitive parsers for parsing single characters, and then combining functions for concatenating parsers or selecting between them. A drawing library might define some basic drawing operations, and then various means of combining drawings into larger ones (on top, beside, above, etc.).<br />
<br />
In this manner, the user of the combinator library builds up the computation they want, piecing together smaller parts into larger ones.<br />
<br />
As far as programming is concerned, a [[monad]] is just a particular style of combinator library. That is, one which supports a few basic means of combination.<br />
<br />
The reason for making this abstraction is so that all the libraries which make use of those means of combination can then share a library of combining functions built up from the primitive ones they are required to support.<br />
<br />
Specifically, by defining an instance of Monad for your library when appropriate, you automatically get the benefit of the functions in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad library] (as well as a few others, like [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html Data.Traversable]). This includes things like for-each loops (forM/mapM), ways to turn pure functions into combiners (liftM2, etc.), as well as other control structures which you get for free just for making your library an instance of Monad.<br />
<br />
=== The parts of a monad ===<br />
<br />
There are of course, other kinds of combinator library, but monads arise fairly naturally from a few basic premises.<br />
<br />
* Monadic computations have results. This is reflected in the types. Given a monad M, a value of type <code>M t</code> is a computation resulting in a value of type <code>t</code>. It's important to realise that this is typically just some data structure. It will be interpreted as a computation and "run" in a way which is dependent on the given library.<br />
* For any value, there is a computation which "does nothing", and produces that result. This is given by defining the function <code>return</code> for the given monad.<haskell><br />
return :: (Monad m) => a -> m a<br />
</haskell><br />
* Given a pair of computations <hask>x</hask> and <hask>y</hask>, one can form the computation <hask>x >> y</hask>, which intuitively "runs" the computation <hask>x</hask>, throws away its result, then runs <hask>y</hask> returning its result.<haskell><br />
(>>) :: (Monad m) => m a -> m b -> m b<br />
</haskell><br />
* Further, we're allowed to use the result of the first computation to decide "what to do next", rather than just throwing it away. This idea is embodied by the operation <hask>(>>=)</hask>, called 'bind'. If <hask>x</hask> is a computation, and <hask>f</hask> is a function from potential results of that computation to further computations to be performed, then <hask>x >>= f</hask> is a computation which runs <hask>x</hask>, then applies <hask>f</hask> to its result, getting a computation which it then runs. The result of this latter computation is the result of the combined one.<haskell><br />
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b<br />
</haskell><br />
<br />
In fact, once we have bind, we can always define <hask>(>>)</hask> as:<br />
<haskell><br />
x >> y = x >>= (\k -> y)<br />
</haskell><br />
<br />
It's important to realise that both what it means to "run" a computation, and what "then" means in the above are both <em>up to the monad in question</em> (subject to a few simple constraints to be discussed later). This point will become clearer as one sees more and more examples.<br />
<br />
=== A few examples ===<br />
<br />
On top of <hask>return</hask> and <hask>(>>=)</hask>, any given monad will typically define a bunch of primitive computations to get the user of the library started. The <hask>IO</hask> monad, for instance, has a large number of I/O operations such as <hask>getLine :: IO String</hask> and <hask>putStrLn :: String -> IO ()</hask>. The program: <haskell><br />
main :: IO ()<br />
main = getLine >>= putStrLn<br />
</haskell> gets a line of text from the user, and then prints it back out.<br />
For a slightly more complicated example, the program: <haskell><br />
main :: IO ()<br />
main = putStrLn "Enter a line of text:"<br />
>> getLine >>= \x -> putStrLn (reverse x)<br />
</haskell> prompts the user for a line of text, gets the line of text from the user, and then prints it back out in reverse.<br />
<br />
A parsing monad might define <hask>char :: Char -> Parser Char</hask>, for constructing a parser which succeeds if the input string matches the given character. As a very simple example without getting into the details of parsing monads, the parser: <haskell><br />
cat = char 'c' >> char 'a' >> char 't' >> return "It's a cat."<br />
</haskell> would try to match the string "cat", and if the parse succeeded, would return the string <hask>"It's a cat."</hask>.<br />
<br />
=== Do notation ===<br />
<br />
Because computations are typically going to be built up from long chains of <hask>(>>)</hask> and <hask>(>>=)</hask>, in Haskell, we have some syntax-sugar, called do-notation.<br />
<br />
The do-notation allows us to write our second IO program above as:<br />
<haskell><br />
main = do putStrLn "Enter a line of text:"<br />
x <- getLine<br />
putStrLn (reverse x)<br />
</haskell><br />
<br />
The basic mechanical translation for the do-notation is as follows:<br />
<haskell><br />
do { x } = x<br />
<br />
do { x ; <stmts> }<br />
= x >> do { <stmts> }<br />
<br />
do { v <- x ; <stmts> }<br />
= x >>= \v -> do { <stmts> }<br />
<br />
do { let <decls> ; <stmts> }<br />
= let <decls> in do { <stmts> }<br />
</haskell><br />
<br />
This gives monadic computations a bit of an imperative feel, but it's important to remember that the monad in question gets to decide what the combination means, and so some unusual forms of control flow might actually occur. In some monads (like parsers, or the list monad), "backtracking" may occur, and in others, even more exotic forms of control might show up (for instance, first-class continuations, or some form of parallelism).<br />
<br />
=== The monad laws ===<br />
<br />
However, in order to maintain some semblance of sanity, we agree to make the monads we define follow some basic rules. I'll show the three rules both in terms of <hask>return</hask> and <hask>(>>=)</hask> and do-notation, and try to give some feel of what they really mean.<br />
<br />
<haskell><br />
1. return v >>= f == f v<br />
<br />
2. x >>= return == x<br />
<br />
3. (x >>= f) >>= g == x >>= (\v -> f v >>= g)<br />
</haskell><br />
<br />
Rules 1 and 2 basically give one the sense that <hask>return v</hask> "does nothing" and results in <hask>v</hask>.<br />
<br />
Rule 3 puts a bit of a constraint on what "then" is supposed to mean. It is perhaps easier at first to look at what it means for <hask>(>>)</hask>:<br />
<haskell><br />
(x >> y) >> z == x >> (y >> z)<br />
</haskell><br />
This corresponds nicely with our usual reading of <hask>(>>)</hask> as "then":<br />
<br />
putting on your tie, <strong>then</strong> (putting on your socks <strong>then</strong> putting on your shoes)<br />
<br />
is the same thing as<br />
<br />
(putting on your tie <strong>then</strong> putting on your socks) <strong>then</strong> putting on your shoes.<br />
<br />
To get a bit of a different perspective on what the laws mean, let's have a look at what they look like in do-notation:<br />
<br />
<haskell><br />
1. do { w <- return v; f w }<br />
== do { f v }<br />
<br />
2. do { v <- x; return v }<br />
== do { x }<br />
</haskell><br />
<br />
These two are again consistent with the idea that return produces a computation that has no "side-effects", and just returns its parameter.<br />
<br />
<haskell><br />
3. do w <- do v <- x<br />
f v<br />
g w<br />
<br />
== do v <- x<br />
w <- f v<br />
g w<br />
</haskell><br />
<br />
This is more interesting. It's telling us that asking for the result of a compound computation in the midst of a do-block will result in exactly the same thing as if that compound computation had been spliced in directly, and gives us a valid way to refactor code written in any monad. We're allowed to abstract a chunk of code out from the middle of a do-block and give it a name without worrying about whether we've changed the meaning of the code.<br />
<br />
=== The whole point ===<br />
<br />
This is all very good, but apart from defining a pretty syntax for a certain kind of combinator library, the stuff we've done so far is fairly inessential. What's the point of recognising something as a monad?<br />
<br />
The point, as I alluded to in the introduction, is that we can then write code which works for all monads, and have a whole library of code which is made available to us just for recognising that the library we're writing happens to be a monad. Since we have only return and bind to work with, this sort of code will serve to chain computations together in some methodical way. That is to say, it will consist of control structures.<br />
<br />
All the examples I'll give are already defined in the [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html Control.Monad] library, along with many more.<br />
<br />
The first example of such a control structure we'll look at is called <hask>sequence</hask>. It's a function which takes a list of computations of the same type, and builds from them a computation which will run each in turn and produce a list of the results:<br />
<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = do v <- x<br />
vs <- sequence xs<br />
return (v:vs)<br />
</haskell><br />
or, without the do-notation:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence [] = return []<br />
sequence (x:xs) = x >>= \v -> sequence xs >>= \vs -> return (v:vs)<br />
</haskell><br />
(one can start to see why do-notation might be desirable!)<br />
<br />
In a parsing monad, we might pass it a list of parsers, and get back a parser which parses its input using each in turn. In the IO monad, a simple example might be the following:<br />
<haskell><br />
main = sequence [getLine, getLine] >>= print<br />
</haskell><br />
which gets two lines of text from the user, and then prints the list.<br />
<br />
Since lists are lazy in Haskell, this gives us a sort of primordial loop from which most other kinds of loops can be built.<br />
<br />
What is a for-each loop really? It's something which performs some action based on each element of a list. So we might imagine a function with the type:<br />
<haskell><br />
forM :: (Monad m) => [a] -> (a -> m b) -> m [b]<br />
</haskell><br />
(as an added bonus, we'll have it collect the results of each iteration).<br />
<br />
We can write this with sequence and map:<br />
<haskell><br />
forM xs f = sequence (map f xs)<br />
</haskell><br />
we apply the function to each element of the list to construct the action for that iteration, and then sequence the actions together into a single computation.<br />
<br />
For example:<br />
<haskell><br />
main = forM [1..10] $ \x -> do<br />
putStr "Looping: "<br />
print x<br />
</haskell><br />
<br />
Since in this, and many other cases, the loop body doesn't produce a particularly interesting result, there are variants of <hask>sequence</hask> and <hask>forM</hask> called <hask>sequence_</hask> and <hask>forM_</hask>, which simply throw the results away as they run each of the actions.<br />
<br />
<haskell><br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ [] = return ()<br />
sequence_ (x:xs) = x >> sequence xs<br />
<br />
forM_ :: (Monad m) => [a] -> (a -> m b) -> m ()<br />
forM_ xs f = sequence_ (map f xs)<br />
</haskell><br />
<br />
Sometimes we only want a computation to happen when a given condition is true. For this, we can write the following:<br />
<haskell><br />
when :: (Monad m) => Bool -> m () -> m ()<br />
when p x = if p then x else return ()<br />
</haskell><br />
Remember that <hask>return ()</hask> is a no-op, so running this computation will run x when the condition is true, and will do nothing at all when the condition fails.<br />
<br />
Another extremely common thing to do is to construct a computation which performs another computation and then applies a function to the result. This can be accomplished by using the <hask>liftM</hask> function:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = do v <- x<br />
return (f v)<br />
</haskell><br />
Or:<br />
<haskell><br />
liftM :: (Monad m) => (a -> b) -> m a -> m b<br />
liftM f x = return . f =<< x<br />
</haskell><br />
where <hask>(=<<)</hask> is just bind with its parameters flipped.<br />
<br />
This is also generalised by <hask>liftM2, liftM3, ...</hask> to running more than one computation before applying a function to the results:<br />
<haskell><br />
liftM2 :: (Monad m) => (a -> b -> c) -> m a -> m b -> m c<br />
liftM2 f x y = do v <- x<br />
w <- y<br />
return (f v w)<br />
</haskell><br />
<br />
It's possible to rewrite sequence in terms of liftM2, return, and a fold over the list:<br />
<haskell><br />
sequence :: (Monad m) => [m a] -> m [a]<br />
sequence xs = foldr (liftM2 (:)) (return []) xs<br />
<br />
sequence_ :: (Monad m) => [m a] -> m ()<br />
sequence_ xs = foldr (>>) (return ()) xs<br />
</haskell><br />
<br />
Anyway, these are just a few of the simpler examples to give a taste of what sorts of control structures you get for free by defining a combinator library as a monad.<br />
<br />
=== Some final notes ===<br />
<br />
It's a common misconception that Haskell uses a monad for I/O out of necessity. Really, it could use any sort of combinator library to describe and combine I/O actions. It just happens that the most obvious way to formulate a library to describe I/O actions ends up being a monad. So we define it as such so as to be able to share all these control structures with other monadic libraries.<br />
<br />
That's really the only reason why we ever define anything as a monad -- the abstraction allows us to make use of a bunch of shared code for free without writing it out over and over again (or worse yet, failing to abstract it at all).<br />
<br />
At this point, you might want to look at some more examples of monads. One place which is a decent starting point for that is [http://www.haskell.org/all_about_monads/html/introII.html Part II of the "All About Monads" tutorial]. You might also have a look at the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Hierarchical Libraries Documentation] for the libraries under Control.Monad.<br />
<br />
-- [[User:CaleGibbard|CaleGibbard]]<br />
<br />
[[Category:Tutorials]] [[Category:Monad]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Cont_computations_as_question-answering_boxes&diff=21123
Cont computations as question-answering boxes
2008-05-30T05:18:13Z
<p>CaleGibbard: </p>
<hr />
<div>== Basic idea and definitions ==<br />
<br />
The basic idea behind the Cont monad is that in place of values of type t, you work with functions of type (t -> r) -> r, where r is some "response" type. Breaking this down a bit, you can think of a function of type t -> r as a question about a value of type t which has a response of type r -- for a yes or no question, r might be Bool, for instance. Then a function of type (t -> r) -> r, is like a box which takes a question about a value of type t, and produces an answer from that question.<br />
<br />
In Haskell syntax, we define a new datatype to wrap up this idea:<br />
<br />
<haskell><br />
newtype Cont r t = Cont ((t -> r) -> r)<br />
-- a value of type Cont r t is of the form Cont f,<br />
-- where f is a function of type (t -> r) -> r<br />
</haskell><br />
<br />
We'd also, for convenience, define a function:<br />
<br />
<haskell><br />
runCont (Cont f) q = f q<br />
</haskell><br />
<br />
Which, given a Cont computation and a question, basically asks the question to get a response.<br />
<br />
The simplest way to make such a box is for the box to just hang on to a value of type t, and answer questions about it truthfully, by simply applying them to the value. (The fun will happen later, when we come up with more twisted ways to get answers.)<br />
<br />
This is embodied in the continuation monad by the function: <br />
<br />
<haskell><br />
return :: t -> Cont r t<br />
-- return takes a value of type t<br />
-- and produces a Cont computation of type t with response type r.<br />
return x = Cont (\q -> q x)<br />
-- produce a Cont computation which given a question q,<br />
-- applies the question to the value x.<br />
</haskell><br />
<br />
(The notation (\x -> ...) is a [[Lambda abstraction]].)<br />
<br />
Now, given a computation of type (Cont r t), and a ''continuation'' which is a function taking a value of type t to some computation of type (Cont r s), we'd like to have a way to join them together, producing a computation of type (Cont r s). That's a bit brain twisting, so let's think about how we might do it...<br />
<br />
We're constructing a box which is going to receive a question q about a value of type s, and has to answer it somehow.<br />
<br />
We have a box, which we'll call x, which answers questions about a value of type t.<br />
<br />
We also have a function, f, which given a value of type t, will give a box which answers a question about a value of type s.<br />
<br />
So what do we do? We ask x the question "if f were applied to your value v of type t, how would the resulting box respond to the question q?"<br />
<br />
The operation which does this funny gluing together is called <code>>>=</code> (pronounced bind), and is implemented like this:<br />
<br />
<haskell><br />
(>>=) :: Cont r t -> (t -> Cont r s) -> Cont r s<br />
x >>= f = Cont (\q -> runCont x (\v -> runCont (f v) q))<br />
</haskell><br />
<br />
So we have what is effectively a fancy version of function application, which instead of working with straightforward values, works with these funky boxes that answer questions about values of the appropriate type.<br />
<br />
== Laws ==<br />
<br />
There are three things which are true of the operations we've defined so far:<br />
<br />
* <code>return v >>= f</code> is the same as <code>f v</code><br />
* <code>x >>= return</code> is the same as <code>x</code><br />
* <code>(x >>= f) >>= g</code> is the same as <code>x >>= (\v -> f v >>= g)</code><br />
<br />
You might want to try to verify them as an exercise. These are the three monad laws, which makes <code>Cont r</code> a monad for any given response type r.<br />
<br />
== Being sneaky: manipulating questions and responses ==<br />
<br />
With only these operations, things are rather boring. The first and second rules above basically tell us that anything we can express just in terms of <code>>>=</code> and <code>return</code>, we can also express without.<br />
<br />
However, by working with black boxes that answer questions about values of type t, rather than values of type t directly, the boxes we construct can take steps to manipulate the question or response.<br />
<br />
Given any function f which turns a question about a value of type s into a question about a value of type t, we can turn a box x which answers questions about a value of type t into a box which answers questions about a value of type s. In code:<br />
<br />
<haskell><br />
withCont :: ((s -> r) -> (t -> r)) -> Cont r t -> Cont r s<br />
withCont f x = Cont (runCont x . f)<br />
</haskell><br />
<br />
That is, simply apply the function to the question first, and then ask x how it would answer.<br />
<br />
Furthermore, given any function (r -> r), which transforms responses somehow, and any box x, we can easily construct a box which asks the box x how it would respond to a question, and then transforms the response.<br />
<br />
<haskell><br />
mapCont :: (r -> r) -> Cont r t -> Cont r t<br />
mapCont f x = Cont (f . runCont x)<br />
</haskell><br />
<br />
You certainly can't do either of these things with plain values! For example, let's consider the value <code>mapCont not (return 0) :: Cont Bool Integer</code>. It is a box that gives the opposite response to any True/False question that one would get if one asked the same question about the number 0. For example, we might do something like:<br />
<br />
<haskell><br />
ghci> runCont (mapCont not (return 0) >>= \t -> return (t < 0 && t > 0)) id<br />
True<br />
</haskell><br />
<br />
The value 't' in the above is apparently a number which gives the appearance of simultaneously being both less than and greater than 0! Of course, what's really happening is that the test is turning out False and being negated after.<br />
<br />
== Being sneakier: Making the result depend directly on the question ==<br />
<br />
There's an interesting insight to be had in thinking about the question that the computation <code>x</code> is given in the application <code>x >>= f</code>.<br />
<br />
The question which x receives involves f, the computation which conceptually 'follows' after x is finished deciding on what value to supply to it. Can a carefully-constructed x somehow sneakily manage to recover the function f from that question, and use it in determining what value it will then supply to that question?<br />
<br />
The answer is that effectively, yes, it can.<br />
<br />
<haskell><br />
callCC :: ((t -> Cont r s) -> Cont r t) -> Cont r t<br />
callCC g = Cont (\q -> runCont (g (\v -> Cont (\_ -> q v))) q)<br />
</haskell><br />
<br />
TODO: Finish the explanation of what this means in terms of the question/answer approach.</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Quotes&diff=20952
Quotes
2008-05-15T04:42:58Z
<p>CaleGibbard: </p>
<hr />
<div><pre><br />
<Philippa> do we have a case of haskell faster than C on a platform where GHC<br />
compiles via C and doesn't screw with the output yet?<br />
<jethr0> wouldn't that just be a blatant case of slow c benchmarking code? :)<br />
<dons> the concurrency or binary tree benchmarks?<br />
<jethr0> someone could put the haskell intermediate c code up as the c benchmark *g*<br />
<musasabi> yes, 30000 lines of C? ;)<br />
%<br />
seen on comp.lang.functional:<br />
<br />
From: Ashley Yakeley <ashley@semantic.org><br />
Subject: Re: Type advocacy<br />
Newsgroups: comp.lang.functional<br />
Date: Thu, 11 Oct 2001 21:16:20 -0700<br />
Organization: Myself<br />
<br />
In article <9pdvgc$u3d$1@news.fas.harvard.edu>, Ken Shan<br />
<ken@digitas.harvard.edu> wrote:<br />
<br />
> I am preparing a three-minute talk to tell incoming graduate students<br />
> at my school about types.<br />
<br />
Oh like that's going to work. You'd be better off selling T-shirts that<br />
say "WHAT PART OF" (and then the Hindley-Milner prinicipal-type<br />
algorithm) "DON'T YOU UNDERSTAND?".<br />
<br />
If anyone gives you any lip, ask them how to find the square-root of a<br />
string. Everything else follows on from that.<br />
<br />
> What pointers should I give?<br />
<br />
Safe ones.<br />
<br />
--<br />
Ashley Yakeley, Seattle WA<br />
%<br />
<kaol> @src liftM<br />
<lambdabot> liftM f m1 = do { x1 <- m1; return (f x1) }<br />
<kaol> @src liftM2<br />
<lambdabot> liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }<br />
<osfameron> does that lift monads which are twice as heavy?<br />
<LoganCapaldo> No, it just lifts a monad in each hand<br />
<osfameron> harr!<br />
<byorgey> you know what they say, a monad in each hand is better than two in<br />
the bush... no wait...<br />
<jfredett> if this were not a family chat channel, I might say something about that...<br />
<DRMacIver> Hand me a long enough monad and I will move the world?<br />
<cjeris> jfredett: yeah, well, the first time I tried to explain what was<br />
different about Haskell to my wife, her response was "Monad? Is that<br />
when you only have one ball?"<br />
%<br />
* EvilTerran . o O ( is a comathematician a device for turning theorems into coffee? )<br />
<oerjan> EvilTerran: no, it's for turning cotheorems into ffee.<br />
<slava> oerjan: it's not clear that the category of cocoffee is isomorphic to ffee<br />
<oerjan> slava: bah, it's mpletely coclear.<br />
%<br />
<roconnor> comonads are just as hard to understand as monads.<br />
<Toxaris> you have to co-understand them?<br />
<quicksilver> Toxaris: I believe you actually have to over-costand them<br />
%<br />
<wli> Modius: nub<br />
<Modius> Thanks<br />
<evir> If this was a gaming channel, one could take that as an insult.<br />
<idnar> evir: wtf stfu<br />
<olsner> how? it's a haskell function - gamers don't know haskell!<br />
<evir> idnar: dieplzkthx<br />
<idnar> evir: lol no u<br />
<EvilTerran> zomglolwut<br />
<idnar> this is vaguely disturbing<br />
<Modius> If I'd have asked for the search clause they would have called you a nubBy<br />
%<br />
<ehird> <interactive>:1:4:<br />
<ehird> My brain just exploded.<br />
<ehird> I can't handle pattern bindings for existentially-quantified constructors.<br />
<ehird> ^_____^<br />
<ehird> I DID IT<br />
<ehird> I DID IT I DID IT I DID IT<br />
<ehird> rite of passage #2: COMPLETE<br />
</pre><br />
<br />
[[Category:Community]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Monomorphism_restriction&diff=20209
Monomorphism restriction
2008-03-25T03:09:45Z
<p>CaleGibbard: </p>
<hr />
<div>The monomorphism restriction is probably the most annoying and controversial feature of Haskell's type system. All seem to agree that it is evil, but whether or not it is considered a necessary evil depends on who you ask.<br />
<br />
The definition of the restriction is fairly technical, but to a first approximation it means that you often cannot overload a function unless you provide an explicit type signature. In summary:<br />
<br />
<haskell><br />
-- This is allowed<br />
f1 x = show x<br />
<br />
-- This is not allowed<br />
f2 = \x -> show x<br />
<br />
-- ...but this is allowed<br />
f3 :: (Show a) => a -> String<br />
f3 = \x -> show x<br />
<br />
-- This is not allowed<br />
f4 = show<br />
<br />
-- ...but this is allowed<br />
f5 :: (Show a) => a -> String<br />
f5 = show<br />
</haskell><br />
<br />
''Call me dense but why exactly is the first one OK and the second one not? -- anonymous''<br />
<br />
:''The difference is that the first version binds x via a "simple pattern binding" (see section 4.4.3.2 of the Haskell 98 report), and is therefore unrestricted, but the second version does not. The reason why one is allowed and the other is not is that it's considered clear that sharing f1 will not share any computation, and less clear that sharing f2 will have the same effect. If this seems arbitrary, that's because it is. It is difficult to design an objective rule which disallows subjective unexpected behaviour. Some people are going to fall foul of the rule even though they're doing quite reasonable things. -- [[Andrew Bromage]]''<br />
<br />
Arguably, these should all be equivalent, but thanks to the monomorphism restriction, they are not.<br />
<br />
So why is the restriction imposed? The reasoning behind it is fairly subtle, and is fully explained in the [http://haskell.org/onlinereport/ Haskell 98 report]. Basically, it solves one practical problem (without the restriction, there would be some ambiguous types) and one semantic problem (without the restriction, there would be some repeated evaluation where a programmer might expect the evaluation to be shared). Those who are for the restriction argue that these cases should be dealt with correctly. Those who are against the restriction argue that these cases are so rare that it's not worth sacrificing the type-independence of eta reduction.<br />
<br />
:An example, from [http://research.microsoft.com/~simonpj/papers/history-of-haskell/index.htm A History of Haskell]: Consider the <code>genericLength</code> function, from <code>Data.List</code><br />
<br />
:<haskell><br />
genericLength :: Num a => [b] -> a<br />
</haskell><br />
<br />
:And consider the function:<br />
<br />
<haskell><br />
f xs = (len,len)<br />
where<br />
len = genericLength xs<br />
</haskell><br />
<br />
:<code>len</code> has type <code>Num a => a</code> and, without the monomorphism restriction, it could be computed ''twice''. --[[User:ARG|ARG]]<br />
<br />
----<br />
<br />
''It is not clear to me how this whole thing about being computed once or twice works. Isn't type checking/inference something that happens at compile-time and shouldn't have any effect on what happens at run-time, as long as the typecheck passes? --dainichi''<br />
<br />
The trouble is that typeclasses essentially introduce additional function parameters -- specifically, the dictionary of code implementing the instances in question. In the case of typeclass polymorphic pattern bindings, you end up turning something that looked like a pattern binding -- a constant that would only ever be evaluated once, into what is really a function binding, something which will not be memoised. [[User:CaleGibbard|CaleGibbard]] 23:46, 1 February 2008 (UTC)<br />
<br />
The type of <code>f</code>, if no signature is given, then the compiler doesn't know that the two elements of the returned pair are of the same type. It's return value will be:<br />
<br />
<haskell><br />
f::(Num a, Num b) => [x] -> (a, b)<br />
</haskell><br />
<br />
This means that <i>while compiling f</i> the compiler is unable to memoise len - clearly if a /= b then different code is executed to compute the first and second appearance of len in the pair. It's possible the compiler could do something more clever <i>when f is actually applied</i> if a == b, but I'm supposing this isn't a straight-forward thing to implement in the compilers. [[User:Dozer|Dozer]] 23:54, 4 February 2008 (GMT)<br />
<br />
----<br />
<br />
Oversimplifying the debate somewhat: Those in favour tend to be those who have written Haskell [[Implementations]] and those against tend to be those who have written complex combinator libraries (and hence have hit their collective heads against the restriction all too often). It often boils down to the fact that programmers want to avoid [http://catb.org/esr/jargon/html/L/legalese.html legalese], and language implementors want to avoid [http://catb.org/esr/jargon/html/C/cruft.html cruft].<br />
<br />
In almost all cases, you can get around the restriction by including explicit type declarations. Those who are for the restriction are usually quick to point out that including explicit type declarations is good programming practice anyway. In a few very rare cases, however, you may need to supply a type signature which is not valid Haskell. (Such type signatures require a type system extension such as [[ScopedTypeVariables]].) Unless you're writing some weird combinator libraries, or are in the habit of not writing type declarations, you're unlikely to come across it. Even so, most Haskell [[Implementations]] provide a way to turn the restriction off.<br />
<br />
See also: [http://haskell.org/onlinereport/decls.html#sect4.5.5 Section 4.5.5, Haskell 98 report].<br />
<br />
-- [[Andrew Bromage]]<br />
<br />
Some question or suggestion: As I understand the problem arises from the situation that two different forms of assignment are described by the same notation. There are two forms of assignment, namely the inspection of data structures ("unpacking", "pattern binding") and the definition of functions ("function binding"). Unique examples are:<br />
<br />
<haskell><br />
let f x = y -- function definition<br />
let F x = y -- data structure decomposition<br />
</haskell><br />
<br />
In the first case we have the identifier f starting with lower case. This means this is a function binding. The second assignment starts with F, which must be a constructor. That's why this is a pattern binding. The monomorphism restriction applies only to the pattern binding. I think this was not defined in order to please compiler writers, but has shown to be useful in practice, or am I wrong? But the different handling of these binding types leads to a problem since both types have a common case.<br />
<br />
<haskell><br />
let x = y -- function or pattern binding?<br />
</haskell><br />
<br />
So, what speaks against differentiating the assignments notationally, say<br />
<br />
<haskell><br />
let f x = y -- function definition<br />
let F x <= y -- data structure decomposition<br />
</haskell><br />
<br />
and keep the monomorphism restriction as it is?<br />
<br />
-- [[Henning Thielemann]]<br />
<br />
The problem isn't just pattern bindings, it's that pattern bindings which are typeclass polymorphic are actually function bindings in disguise, since the usual implementation of typeclasses adds parameters to such definitions, to allow the definition to take the typeclass dictionaries involved. Thus, such pattern bindings have different properties with respect to sharing (they're generally less shared than you want). In especially bad cases, without the MR, it is possible to have programs which run exponentially slower without type signatures than when signatures are added. Just distinguishing pattern bindings with a new notation doesn't solve the problem, since they'll have to be converted into function bindings in that case anyway. If you intend to keep the MR, then you don't need to change anything. The issue with the MR is just the fact that it's annoying to have eta-reduction fail in the absence of explicit type signatures, and the fact that it makes otherwise perfectly valid programs fail to compile on speculation that there might be loss of sharing (when there usually isn't, or at least the impact isn't large enough to worry about).<br />
<br />
John Hughes recently advocated the removal of the MR on the Haskell Prime mailing list, and suggested replacing it with two forms of pattern binding: one for call-by-name (polymorphic, not shared), and one for call-by-need (monomorphic, guaranteed shared). This might be similar to what you're suggesting. If you look at it too closely, it seems like a good solution, but the overall impact on Haskell code seems too large to me, to resolve a distinction which it ought to be statically possible to determine.<br />
<br />
I'm of the opinion that it would be better to find a way to restore sharing lost through the typeclass transformation in some way, or else implement typeclasses in an altogether different way which doesn't run into this problem. Additional runtime machinery seems like a likely candidate for this -- the interactions with garbage collection are somewhat subtle, but I think it should be doable. It's also possible to restore the sharing via whole-program analysis, but advocates of separate compilation will probably complain, unless we were to find a mechanism to fix the problem from the object code (and potentially temporaries) at link time.<br />
<br />
:- [[Cale Gibbard]]<br />
<br />
--------------------<br />
I think it'd be useful to collect a set of examples of the Monormorphism Restriction biting people in an unexpected way. This may help to inform the debate over the MR by giving real-life examples. Add more examples here if (an only if) they constitute an unexpected MR-related incident in your life or someone else's. No invented examples! -- [[Simon Peyton Jones]]<br />
<br />
* GHC Trac bug [http://hackage.haskell.org/trac/ghc/ticket/1749 1749]<br />
* In trying to build an editor with undoable actions:<br />
<haskell><br />
class EditAction e a | e -> a where<br />
apply :: a -> e -> a<br />
<br />
data ListAction a = Append a | Remove<br />
<br />
instance EditAction (ListAction a) [a] where<br />
apply list (Append a) = a:list<br />
apply (x:xs) Remove = xs<br />
<br />
-- Apply all the EditActions to the input<br />
--edit :: EditAction e a => a -> [e] -> a -- monomorphism restriction - I have to put this in!<br />
edit = foldl apply<br />
</haskell><br />
<br />
----<br />
Back before forM was in the Control.Monad library, I once spent about 1/2 an hour trying to figure out why my action in the ST monad was having its '<hask>s</hask>' parameter squished to <hask>()</hask>. I tore the code apart for quite a while before discovering that it was that the MR was applying to my definition of <hask>forM</hask>:<br />
<br />
<haskell><br />
forM = flip mapM<br />
</haskell><br />
<br />
----<br />
<br />
[[Category:Glossary]]<br />
[[Category:Language]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19603
Talk:Euler problems/Answers
2008-02-27T14:43:29Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
::::If we thought it a good idea to publish the answer in advance we would have done that already, instead of letting people find out that some wiki has them. Moreover sometimes problems change, or their answer changes. So it would be better, provided that we thought it a good idea to prepublish those numbers, that we did that ourselves.[[User:hk|hk]]<br />
<br />
:::::That sounds like a good idea to me. Then you can keep them up to date, and other people don't have to worry so much about doing that. Why don't you? I'm sure that others would feel less inclined to bother if the Project Euler site already contained a well-maintained public list of the solutions. [[User:CaleGibbard|CaleGibbard]] 16:26, 26 February 2008 (UTC)<br />
<br />
::::::mathschallenge.net is another site from the makers of project euler that does keep a list of solutions to every problem. However maths challenges isn't nearly as popular as Project Euler, even though the question are of the same difficulty. [[User:Pokerke|Pokerke]]<br />
<br />
:::::::Hey, thanks for pointing me at mathschallenge.net. Looking at it, many of the problems are still sort of lame, but there are a few at least which actually appear to have motivating consequences. [[User:CaleGibbard|CaleGibbard]] 18:21, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]<br />
<br />
:If I understand correctly, the complaint is that each numerical answer is considered proof of a solution and thus allows access to the appropriate problem forum, and by publishing them here we subvert that proof. Is that right? &mdash;[[User:Ashley Y|Ashley Y]] 02:12, 27 February 2008 (UTC)<br />
<br />
::That is correct :-) [[User: Pokerke|Pokerke]]<br />
<br />
::<em>Except</em> that said number cannot really be considered proof anyway, since other people could always publish lists of solutions like this, even if it's not us. It's really more a problem with the design of PE, not with anyone else's willingness to publish the list of solutions. In fact, simply because we've had all of this annoyance, I'm seriously considering maintaining such a list on my own site. It's not so much that I think that it's terribly useful (though it is certainly of some use to those working on solutions, allowing them to quickly check solutions offline, or indeed, to access the PE forums when they'd otherwise given up on trying to solve the problem), or that I think the Haskell Wiki is the ideal place for such a list (indeed PE's own site would be the best place). It's really more a matter of principle. Censorship over a matter like this, when we would be entirely within our rights to keep the page, and it is indeed beneficial to some Haskell users, seems really excessive. [[User:CaleGibbard|CaleGibbard]] 14:43, 27 February 2008 (UTC)<br />
<br />
OK. I'm leaning towards deleting this particular page on the grounds that it is very little contribution to Haskell, and annoys some people sufficiently to cause trouble.<br />
<br />
Sorry for the long process, this is our first content dispute and I don't want to annoy anyone. &mdash;[[User:Ashley Y|Ashley Y]] 08:39, 27 February 2008 (UTC)</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19602
Talk:Euler problems/Answers
2008-02-27T14:43:09Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
::::If we thought it a good idea to publish the answer in advance we would have done that already, instead of letting people find out that some wiki has them. Moreover sometimes problems change, or their answer changes. So it would be better, provided that we thought it a good idea to prepublish those numbers, that we did that ourselves.[[User:hk|hk]]<br />
<br />
:::::That sounds like a good idea to me. Then you can keep them up to date, and other people don't have to worry so much about doing that. Why don't you? I'm sure that others would feel less inclined to bother if the Project Euler site already contained a well-maintained public list of the solutions. [[User:CaleGibbard|CaleGibbard]] 16:26, 26 February 2008 (UTC)<br />
<br />
::::::mathschallenge.net is another site from the makers of project euler that does keep a list of solutions to every problem. However maths challenges isn't nearly as popular as Project Euler, even though the question are of the same difficulty. [[User:Pokerke|Pokerke]]<br />
<br />
:::::::Hey, thanks for pointing me at mathschallenge.net. Looking at it, many of the problems are still sort of lame, but there are a few at least which actually appear to have motivating consequences. [[User:CaleGibbard|CaleGibbard]] 18:21, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]<br />
<br />
:If I understand correctly, the complaint is that each numerical answer is considered proof of a solution and thus allows access to the appropriate problem forum, and by publishing them here we subvert that proof. Is that right? &mdash;[[User:Ashley Y|Ashley Y]] 02:12, 27 February 2008 (UTC)<br />
<br />
::That is correct :-) [[User: Pokerke|Pokerke]]<br />
<br />
::*Except* that said number cannot really be considered proof anyway, since other people could always publish lists of solutions like this, even if it's not us. It's really more a problem with the design of PE, not with anyone else's willingness to publish the list of solutions. In fact, simply because we've had all of this annoyance, I'm seriously considering maintaining such a list on my own site. It's not so much that I think that it's terribly useful (though it is certainly of some use to those working on solutions, allowing them to quickly check solutions offline, or indeed, to access the PE forums when they'd otherwise given up on trying to solve the problem), or that I think the Haskell Wiki is the ideal place for such a list (indeed PE's own site would be the best place). It's really more a matter of principle. Censorship over a matter like this, when we would be entirely within our rights to keep the page, and it is indeed beneficial to some Haskell users, seems really excessive. [[User:CaleGibbard|CaleGibbard]] 14:43, 27 February 2008 (UTC)<br />
<br />
OK. I'm leaning towards deleting this particular page on the grounds that it is very little contribution to Haskell, and annoys some people sufficiently to cause trouble.<br />
<br />
Sorry for the long process, this is our first content dispute and I don't want to annoy anyone. &mdash;[[User:Ashley Y|Ashley Y]] 08:39, 27 February 2008 (UTC)</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19590
Talk:Euler problems/Answers
2008-02-26T18:21:25Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
::::If we thought it a good idea to publish the answer in advance we would have done that already, instead of letting people find out that some wiki has them. Moreover sometimes problems change, or their answer changes. So it would be better, provided that we thought it a good idea to prepublish those numbers, that we did that ourselves.[[User:hk|hk]]<br />
<br />
:::::That sounds like a good idea to me. Then you can keep them up to date, and other people don't have to worry so much about doing that. Why don't you? I'm sure that others would feel less inclined to bother if the Project Euler site already contained a well-maintained public list of the solutions. [[User:CaleGibbard|CaleGibbard]] 16:26, 26 February 2008 (UTC)<br />
<br />
::::::mathschallenge.net is another site from the makers of project euler that does keep a list of solutions to every problem. However maths challenges isn't nearly as popular as Project Euler, even though the question are of the same difficulty. [[User:Pokerke|Pokerke]]<br />
<br />
:::::::Hey, thanks for pointing me at mathschallenge.net. Looking at it, many of the problems are still sort of lame, but there are a few at least which actually appear to have motivating consequences. [[User:CaleGibbard|CaleGibbard]] 18:21, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19586
Talk:Euler problems/Answers
2008-02-26T16:27:51Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
::::If we thought it a good idea to publish the answer in advance we would have done that already, instead of letting people find out that some wiki has them. Moreover sometimes problems change, or their answer changes. So it would be better, provided that we thought it a good idea to prepublish those numbers, that we did that ourselves.[[User:hk|hk]]<br />
<br />
:::::That sounds like a good idea to me. Then you can keep them up to date, and other people don't have to worry so much about doing that. Why don't you? I'm sure that others would feel less inclined to bother if the Project Euler site already contained a well-maintained public list of the solutions. [[User:CaleGibbard|CaleGibbard]] 16:26, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19585
Talk:Euler problems/Answers
2008-02-26T16:26:46Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
::::If we thought it a good idea to publish the answer in advance we would have done that already, instead of letting people find out that some wiki has them. Moreover sometimes problems change, or their answer changes. So it would be better, provided that we thought it a good idea to prepublish those numbers, that we did that ourselves.[[User:hk|hk]]<br />
<br />
:::::That sounds like a good idea to me. Then you can keep them up to date, and other people don't have to worry so much about doing that. Why don't you? [[User:CaleGibbard|CaleGibbard]] 16:26, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Power_function&diff=19583
Power function
2008-02-26T16:24:30Z
<p>CaleGibbard: </p>
<hr />
<div>== Question ==<br />
<br />
Why are there several notions of power in Haskell, namely <hask>(^)</hask>, <hask>(^^)</hask>, <hask>(**)</hask>?<br />
<br />
<br />
== Answer ==<br />
<br />
The reason is that there is no definition for the power function which covers all exotic choices for basis and exponent.<br />
It is even sensible to refine the set of power functions as it is done in the [http://darcs.haskell.org/numericprelude/ NumericPrelude] project.<br />
In mathematical notation we don't respect types and we do not distinguish between powers of different types.<br />
However if we assume the most general types for both basis and exponent, the result of the power is no longer unique.<br />
Actually all possible solutions of say <math>1^x</math>,<br />
where <math>x</math> is irrational is dense in the complex unit circle.<br />
In the past I needed the power of two complex numbers only once, namely for the [http://www.math.uni-bremen.de/~thielema/Research/cwt.pdf Cauchy wavelet] (see also: [http://ieeexplore.ieee.org/iel5/78/18506/00852022.pdf?arnumber=852022]):<br />
: <math> f(t) = (1- i\cdot k\cdot t) ^ {-\frac{1}{2} + \frac{\mu_2}{k} + i\cdot \mu_1 } </math><br />
However, I could not use the built-in complex power function<br />
because the resulting function became discontinuous.<br />
Of course, powers of complex numbers have the problem of branch cuts and<br />
the choice of the branch built into the implementation of the complex power is quite arbitrary and<br />
might be inappropriate.<br />
<br />
But also for real numbers there are problems:<br />
For computing <hask>(-1)**(1/3::Double)</hask> the power implementation has to decide whether <br />
<hask>(1/3::Double)</hask> is close enough to <math>\frac{1}{3}</math>.<br />
If it does so it returns <hask>(-1)</hask>, otherwise it fails.<br />
However, why shall <hask>0.333333333333333</hask> represent <math>\frac{1}{3}</math>?<br />
It may be really meant as <hask>333333333333333/10^15</hask>,<br />
and a real <math>10^{15}</math>th root of <math>-1</math> does not exist.<br />
<br />
So I propose some balancing: The more general the basis the less general the exponent and vice versa.<br />
I also think the following symbols are more systematic and intuitive.<br />
They are used in NumericPrelude.<br />
{|<br />
| basis type || provides || symbol || exponent type || definition ||<br />
|-<br />
| any ring || <hask> * </hask> || <hask> ^ </hask> || cardinal || repeated multiplication || <math>a^b = \prod_{i=1}^b a </math><br />
|-<br />
| any field || <hask> / </hask> || <hask> ^- </hask> || integer || multiplication and division || <math>a^b = \begin{cases} a^b & b\ge 0 \\ \frac{1}{a^{-b}} & b<0 \end{cases} </math><br />
|-<br />
| an algebraic field || <hask>root</hask> || <hask> ^/ </hask> || rational || list of polynomial zeros (length = denominator of the exponent) || <math> a^{\frac{p}{q}} = \{ x : a^p = x^q \} </math><br />
|-<br />
| positive real || <hask> log </hask> || ^? || any ring of characteristic zero with inverses for integers and a notion of limit || exponential series and logarithm || <math>a^b = \exp(b \log a) = \sum_{k \geq 0} \frac{(b \log a)^k}{k!} = \sum_{k \geq 0} \frac{\left(- b \sum_{j \geq 1} \frac{(1-a)^j}{j}\right)^k}{k!} </math><br />
|}<br />
<br />
* examples for rings are: Polynomials, Matrices, Residue classes<br />
* examples for fields: Fractions of polynomials (rational functions), Residue classes with respect to irreducible divisors, in fact we do not need fields, we only need the division and associativity, thus invertible Matrices are fine<br />
<br />
<br />
That is <hask>(^-)</hask> replaces <hask>(^^)</hask>,<br />
<hask>(^?)</hask> replaces <hask>(**)</hask>,<br />
<hask>(^)</hask> remains and <hask>(^/)</hask> is new.<br />
<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2006-April/015329.html Proposal for restructuring Number classes]<br />
<br />
[[Category:Mathematics]]<br />
[[Category:FAQ]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Power_function&diff=19582
Power function
2008-02-26T16:23:44Z
<p>CaleGibbard: </p>
<hr />
<div>== Question ==<br />
<br />
Why are there several notions of power in Haskell, namely <hask>(^)</hask>, <hask>(^^)</hask>, <hask>(**)</hask>?<br />
<br />
<br />
== Answer ==<br />
<br />
The reason is that there is no definition for the power function which covers all exotic choices for basis and exponent.<br />
It is even sensible to refine the set of power functions as it is done in the [http://darcs.haskell.org/numericprelude/ NumericPrelude] project.<br />
In mathematical notation we don't respect types and we do not distinguish between powers of different types.<br />
However if we assume the most general types for both basis and exponent, the result of the power is no longer unique.<br />
Actually all possible solutions of say <math>1^x</math>,<br />
where <math>x</math> is irrational is dense in the complex unit circle.<br />
In the past I needed the power of two complex numbers only once, namely for the [http://www.math.uni-bremen.de/~thielema/Research/cwt.pdf Cauchy wavelet] (see also: [http://ieeexplore.ieee.org/iel5/78/18506/00852022.pdf?arnumber=852022]):<br />
: <math> f(t) = (1- i\cdot k\cdot t) ^ {-\frac{1}{2} + \frac{\mu_2}{k} + i\cdot \mu_1 } </math><br />
However, I could not use the built-in complex power function<br />
because the resulting function became discontinuous.<br />
Of course, powers of complex numbers have the problem of branch cuts and<br />
the choice of the branch built into the implementation of the complex power is quite arbitrary and<br />
might be inappropriate.<br />
<br />
But also for real numbers there are problems:<br />
For computing <hask>(-1)**(1/3::Double)</hask> the power implementation has to decide whether <br />
<hask>(1/3::Double)</hask> is close enough to <math>\frac{1}{3}</math>.<br />
If it does so it returns <hask>(-1)</hask>, otherwise it fails.<br />
However, why shall <hask>0.333333333333333</hask> represent <math>\frac{1}{3}</math>?<br />
It may be really meant as <hask>333333333333333/10^15</hask>,<br />
and a real <math>10^{15}</math>th root of <math>-1</math> does not exist.<br />
<br />
So I propose some balancing: The more general the basis the less general the exponent and vice versa.<br />
I also think the following symbols are more systematic and intuitive.<br />
They are used in NumericPrelude.<br />
{|<br />
| basis type || provides || symbol || exponent type || definition ||<br />
|-<br />
| any ring || <hask> * </hask> || <hask> ^ </hask> || cardinal || repeated multiplication || <math>a^b = \prod_{i=1}^b a </math><br />
|-<br />
| any field || <hask> / </hask> || <hask> ^- </hask> || integer || multiplication and division || <math>a^b = \begin{cases} a^b & b\ge 0 \\ \frac{1}{a^{-b}} & b<0 \end{cases} </math><br />
|-<br />
| an algebraic field || <hask>root</hask> || <hask> ^/ </hask> || rational || list of polynomial zeros (length = denominator of the exponent) || <math> a^{\frac{p}{q}} = \{ x : a^p = x^q \} </math><br />
|-<br />
| positive real || <hask> log </hask> || ^? || any ring of characteristic zero with a notion of limit || exponential series and logarithm || <math>a^b = \exp(b \log a) = \sum_{k \geq 0} \frac{(b \log a)^k}{k!} = \sum_{k \geq 0} \frac{\left(- b \sum_{j \geq 1} \frac{(1-a)^j}{j}\right)^k}{k!} </math><br />
|}<br />
<br />
* examples for rings are: Polynomials, Matrices, Residue classes<br />
* examples for fields: Fractions of polynomials (rational functions), Residue classes with respect to irreducible divisors, in fact we do not need fields, we only need the division and associativity, thus invertible Matrices are fine<br />
<br />
<br />
That is <hask>(^-)</hask> replaces <hask>(^^)</hask>,<br />
<hask>(^?)</hask> replaces <hask>(**)</hask>,<br />
<hask>(^)</hask> remains and <hask>(^/)</hask> is new.<br />
<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2006-April/015329.html Proposal for restructuring Number classes]<br />
<br />
[[Category:Mathematics]]<br />
[[Category:FAQ]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Power_function&diff=19581
Power function
2008-02-26T16:22:37Z
<p>CaleGibbard: </p>
<hr />
<div>== Question ==<br />
<br />
Why are there several notions of power in Haskell, namely <hask>(^)</hask>, <hask>(^^)</hask>, <hask>(**)</hask>?<br />
<br />
<br />
== Answer ==<br />
<br />
The reason is that there is no definition for the power function which covers all exotic choices for basis and exponent.<br />
It is even sensible to refine the set of power functions as it is done in the [http://darcs.haskell.org/numericprelude/ NumericPrelude] project.<br />
In mathematical notation we don't respect types and we do not distinguish between powers of different types.<br />
However if we assume the most general types for both basis and exponent, the result of the power is no longer unique.<br />
Actually all possible solutions of say <math>1^x</math>,<br />
where <math>x</math> is irrational is dense in the complex unit circle.<br />
In the past I needed the power of two complex numbers only once, namely for the [http://www.math.uni-bremen.de/~thielema/Research/cwt.pdf Cauchy wavelet] (see also: [http://ieeexplore.ieee.org/iel5/78/18506/00852022.pdf?arnumber=852022]):<br />
: <math> f(t) = (1- i\cdot k\cdot t) ^ {-\frac{1}{2} + \frac{\mu_2}{k} + i\cdot \mu_1 } </math><br />
However, I could not use the built-in complex power function<br />
because the resulting function became discontinuous.<br />
Of course, powers of complex numbers have the problem of branch cuts and<br />
the choice of the branch built into the implementation of the complex power is quite arbitrary and<br />
might be inappropriate.<br />
<br />
But also for real numbers there are problems:<br />
For computing <hask>(-1)**(1/3::Double)</hask> the power implementation has to decide whether <br />
<hask>(1/3::Double)</hask> is close enough to <math>\frac{1}{3}</math>.<br />
If it does so it returns <hask>(-1)</hask>, otherwise it fails.<br />
However, why shall <hask>0.333333333333333</hask> represent <math>\frac{1}{3}</math>?<br />
It may be really meant as <hask>333333333333333/10^15</hask>,<br />
and a real <math>10^{15}</math>th root of <math>-1</math> does not exist.<br />
<br />
So I propose some balancing: The more general the basis the less general the exponent and vice versa.<br />
I also think the following symbols are more systematic and intuitive.<br />
They are used in NumericPrelude.<br />
{|<br />
| basis type || provides || symbol || exponent type || definition ||<br />
|-<br />
| any ring || <hask> * </hask> || <hask> ^ </hask> || cardinal || repeated multiplication || <math>a^b = \prod_{i=1}^b a </math><br />
|-<br />
| any field || <hask> / </hask> || <hask> ^- </hask> || integer || multiplication and division || <math>a^b = \begin{cases} a^b & b\ge 0 \\ \frac{1}{a^{-b}} & b<0 \end{cases} </math><br />
|-<br />
| an algebraic field || <hask>root</hask> || <hask> ^/ </hask> || rational || list of polynomial zeros (length = denominator of the exponent) || <math> a^{\frac{p}{q}} = \{ x : a^p = x^q \} </math><br />
|-<br />
| positive real || <hask> log </hask> || ^? || any ring with a notion of limit || exponential series and logarithm || <math>a^b = \exp(b \log a) = \sum_{k \geq 0} \frac{(b \log a)^k}{k!} = \sum_{k \geq 0} \frac{\left(- b \sum_{j \geq 1} \frac{(1-a)^j}{j}\right)^k}{k!} </math><br />
|}<br />
<br />
* examples for rings are: Polynomials, Matrices, Residue classes<br />
* examples for fields: Fractions of polynomials (rational functions), Residue classes with respect to irreducible divisors, in fact we do not need fields, we only need the division and associativity, thus invertible Matrices are fine<br />
<br />
<br />
That is <hask>(^-)</hask> replaces <hask>(^^)</hask>,<br />
<hask>(^?)</hask> replaces <hask>(**)</hask>,<br />
<hask>(^)</hask> remains and <hask>(^/)</hask> is new.<br />
<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2006-April/015329.html Proposal for restructuring Number classes]<br />
<br />
[[Category:Mathematics]]<br />
[[Category:FAQ]]</div>
CaleGibbard
https://wiki.haskell.org/index.php?title=Talk:Euler_problems/Answers&diff=19579
Talk:Euler problems/Answers
2008-02-26T16:03:28Z
<p>CaleGibbard: </p>
<hr />
<div>What are you up to?<br />
This has nothing to do with programming in Haskell.<br />
Please stop mistreating Project Euler and use the username you use on Project Euler so that we are able to locate the user that does this kind of things.<br />
<br />
----<br />
<br />
Anybody restoring the disgusting contents of this page is willingly infringing again. That cannot be considered as ignorant behaviour.<br />
[[User: hk|hk]]<br />
<br />
----<br />
<br />
This page has totally nothing to do with Haskell, and therefore doesn't belong in an Haskell wiki.<br />
<br />
----<br />
Cale, call me a Vandal if you wish, but this is utterly disgusting. [[User:Daniel.is.fischer|Daniel.is.fischer]]<br />
<br />
----<br />
I already tried this before, but he just reverted the page..<br />
<br />
The Project Euler problems are copyrighted under the creative commons license. http://projecteuler.net/index.php?section=copyright http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ Legal version http://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode If you read this you will see that the simple permissive license is not identical to the creative commons licence. The share alike condition reads: "Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a licence identical to this one."<br />
<br />
[[User:henk263|henk263]]<br />
<br />
----<br />
<br />
I disagree that a list of numbers could even potentially infringe on the copyright. First of all, where does this list of numbers appear in the copyrighted material? Secondly, it is clearly a tiny fraction of Project Euler's work and would reasonably fall under fair use.<br />
<br />
[[User:CaleGibbard|CaleGibbard]] 10:21, 24 February 2008 (UTC)<br />
<br />
----<br />
<br />
I also believe that copyright doesn't apply here.<br />
<br />
However, I don't see how this page helps to promote Haskell or serves any purpose besides upsetting the Project Euler folks.<br />
<br />
This page is a lot different in that regard from the other disputed pages that contain actual solutions, mostly written in Haskell, which serve an educational purpose. (n.b. I have not actually read them, I'm going by the discussion.)<br />
<br />
[[User:Int-e|Int-e]] 01:17, 25 February 2008 (UTC)<br />
<br />
:I protected this page due to the edit war, but I'm not necessarily against deleting it. What do other people think? &mdash;[[User:Ashley Y|Ashley Y]] 01:24, 25 February 2008 (UTC)<br />
<br />
::I also have no problem with deleting this. It doesn't help Haskell any, and just upsets people needlessly. I want to see code and ideas[[User:DonStewart|dons]] 04:06, 25 February 2008 (UTC)<br />
<br />
The page doesn't take up much space, and would be useful for people testing regressions while working on solutions. I'd rather it stay.<br />
[[User:CaleGibbard|CaleGibbard]] 04:40, 25 February 2008 (UTC)<br />
<br />
I agree with those who would like this page removed. It serves no useful purpose (it's easy to test possible solutions directly on the Project Euler site) and has nothing to do with Haskell. [[User:Robinrobin|Robinrobin]] 12:15, 25 February 2008 (UTC)<br />
<br />
To help you in your discussion about the usefulness of this page:<br />
I altered the limit for problem 10, so the answer here is not valid any more.<br />
Moreover: if the new answer appears here, I will change the limit for this problem again. I'm planning to do so for some other problems but will not give any notification about which problem and when. I thought it fair play to notify you.<br />
[[User:hk|hk]]<br />
<br />
:Hk, what's your issue with this page? Surely the solutions to the problems are ''programs'' rather than the numbers they output, so are the numbers even spoilers? &mdash;[[User:Ashley Y|Ashley Y]] 11:17, 26 February 2008 (UTC)<br />
<br />
::To me the numbers are more spoilers than the programs. There has been ample evidence of childish people that have been "solving" problems using OEIS. (Yes the answers to some of the earlier problems can be easily found on OEIS, currently we try to exclude that possibilty, although we make a slip sometimes). In due time this list here will be googlable. Even the knowledge that such a list exits will be spoiling the pleasure for some people.I have in fact no objections to some (not too many) programs that show how to solve a problem e.g in Haskell. E.g. I would love to see how problem 10 could be solved using a primesieve in Haskell. The current "solution" tells me nothing about that. In fact the list of answers to our problems are the keywords to our site. Why do you think we only allow people access to the forum of a problem after providing the correct answer? What this list here does is overthrowing the entire concept of Project Euler.[[User: hk|hk]]<br />
<br />
:::Forgive me if I'm wrong, as I haven't really participated much in Project Euler, but given the FAQ, isn't the entire concept basically to provide a bunch of problems for people to work on? I don't see how publishing the solutions, even in an otherwise unilluminating way, could possibly compromise that goal. People who want to solve the problems on their own can still do so, no? Oh, and if you'd like to see a proper prime sieve in Haskell, [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf this paper] would be of interest. [[User:CaleGibbard|CaleGibbard]] 15:54, 26 February 2008 (UTC)<br />
:::I'd also like to add that in my experience, knowing *a* solution to some problem does not tend to spoil the problem. One can always look for others, and still have fun doing it. [[User:CaleGibbard|CaleGibbard]] 16:03, 26 February 2008 (UTC)<br />
<br />
Just noticed the discussion over here. I think these answers add very little to the Haskell wiki. When someone is using Google to find the answer to a certain PE problem, and comes across the Haskell solution, he has to learn Haskell a little, download an Haskell compiler and experiment with it a bit. That would benefit the Haskell community imho. This answer page on the other hand doesn't require people to learn any Haskell at all and makes it easier to "cheat". (the user is only cheating on himself in my opinion, but still). Also, this list of numbers seems to annoy PE users quite a lot and has very little to do with Haskell, so I say remove it.<br />
<br />
The Haskell (and not the C++) solutions to PE problems are very usefull I think, and assist in learning Haskell.[[User: Pokerke|Pokerke]]</div>
CaleGibbard