<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:at="http://www.sixapart.com/ns/at"
    xmlns:icbm="http://postneo.com/icbm"
    xmlns:rvw="http://purl.org/NET/RVW/0.2/"
    xmlns:media="http://search.yahoo.com/mrss">
    <channel>
        <title>osfameron’s blog</title>
        <link>http://osfameron.vox.com/library/posts/tags/haskell/page/1/</link>
        <description></description>
        <language>en</language>
        <generator>Vox</generator>
        <lastBuildDate>Fri, 20 Jun 2008 08:32:16 +0100</lastBuildDate>
        <copyright>Copyright 2008</copyright>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs> 
        <category domain="http://osfameron.vox.com/tags/">haskell</category>  
 
        <item>
            <title>More Countdown: laziness, Scheme, and German frogs</title>
            <link>http://osfameron.vox.com/library/post/more-countdown-laziness-scheme-and-german-frogs.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/more-countdown-laziness-scheme-and-german-frogs.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/more-countdown-laziness-scheme-and-german-frogs.html?_c=feed-rss-full</guid> 
            <pubDate>Fri, 20 Jun 2008 08:32:16 +0100</pubDate>         
            
            <description>    &lt;p&gt;
The Countdown code I showed you isn&amp;#39;t really taking advantage of Haskell&amp;#39;s laziness.
We should only have to check entries up until the point that we have enough matches
(in the current code &amp;#39;&lt;tt&gt;take 4 $ getAnagrams&lt;/tt&gt;&amp;#39;) and that&amp;#39;s good.  However, we
have to generate the whole powerset first, so that we can sort it in reverse order
of length.  Ideally, we&amp;#39;d generate the powerset breadth-first, in order of length.
&lt;/p&gt;

&lt;p&gt;
OK, so generating the powerset doesn&amp;#39;t take all that much time and this isn&amp;#39;t a good
&lt;em&gt;optimization&lt;/em&gt; as such, but I did think it might be fun trying to do the breadth
first powerset, as all the examples I&amp;#39;d seen had been depth first.
&lt;/p&gt;

&lt;p&gt;
But first: an interlude to marvel at one of the scariest things I&amp;#39;ve seen this year.
A &lt;a href=&quot;http://community.livejournal.com/evan_tech/220036.html&quot;&gt;monadic definition of
powerset&lt;/a&gt;.

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;import Control.Monad (filterM)&lt;br /&gt;powerset = filterM (const [True, False])&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;

I&amp;#39;m not even going to attempt to twist my head around that now, but it&amp;#39;s very beautiful,
though it&amp;#39;s impossible to tell just by reading it what the intent of the code is.


&lt;p&gt;
I asked on #london.pm if anyone knew good breadth-first algorithms for powerset.  Joel
helpfully pasted the following

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;(define (combinations set n)&lt;br /&gt;  (if (zero? n)&lt;br /&gt;    (list &amp;#39;())&lt;br /&gt;    (let ((n2 (- n 1)))&lt;br /&gt;      (pair-fold-right&lt;br /&gt;       (lambda (pr acc)&lt;br /&gt;         (let ((first (car pr)))&lt;br /&gt;           (append (map (cut cons first &amp;lt;&amp;gt;)&lt;br /&gt;                        (combinations (cdr pr) n2))&lt;br /&gt;                   acc)))&lt;br /&gt;       &amp;#39;()&lt;br /&gt;       set))))&lt;br /&gt; &lt;br /&gt;(define (power-set set)&lt;br /&gt;  (let ((size (length set)))&lt;br /&gt;    (let loop ((i 0))&lt;br /&gt;      (if (&amp;gt; i size)&lt;br /&gt;        &amp;#39;()&lt;br /&gt;        (append (combinations set i)&lt;br /&gt;                (loop (+ i 1)))))))&lt;/pre&gt;&lt;/blockquote&gt;

I think it surprised Joel (and actually, it surprised me a little) that I was more or less
unable to read this at all.  Yes, I know that the syntax of Lisp is incredibly simple, and
you can learn all the syntax of Scheme in 20 minutes or whatever.  The noise of the
parenthesis, the &lt;tt&gt;cdr&lt;/tt&gt;s etc. is just noise, you can filter it out if you look at
it calmly. But I still don&amp;#39;t understand where the pairs are in &lt;tt&gt;pair-fold-right&lt;/tt&gt;,
and &lt;tt&gt;cut&lt;/tt&gt; apparently does something similar to currying, but what does that &lt;em&gt;mean&lt;/em&gt;
in context?&lt;/p&gt;

&lt;p&gt;
To cut a long story short, I was reading this as a foreign language rather than a piece of
generic pseudocode.  When I was very little, I read with my mother a picture book about
frogs, in German.  With the help of the pictures and a little imagination, it was easy to
tell which word meant &amp;quot;frog&amp;quot;, which meant &amp;quot;tree&amp;quot;, and what the sense of the story was.
After we finished, very puffed up with just how damn clever I was, I started trying to
read it again, and got utterly confused about all these strange words like &amp;#39;&lt;tt&gt;in&lt;/tt&gt;&amp;#39; 
and &amp;#39;&lt;tt&gt;auf&lt;/tt&gt;&amp;#39; and &amp;#39;&lt;tt&gt;dem&lt;/tt&gt;&amp;#39; that I just hadn&amp;#39;t worried about the first time
around.
&lt;/p&gt;
&lt;p&gt;
So... trying to see the frog for the trees, we can see that
&lt;tt&gt;combinations&lt;/tt&gt; gives every set of combinations of a particular length,
and that &lt;tt&gt;power-set&lt;/tt&gt; merely loops through &lt;tt&gt;0..length&lt;/tt&gt;, appending the
combinations found for that length.
&lt;/p&gt;

&lt;p&gt;
We can write combinations as a variant on the original powerset function, but which refuses
to carry on once it&amp;#39;s got enough letters:

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;combinations xs n = comb&amp;#39; xs n (length xs)&lt;br /&gt;&lt;br /&gt;comb&amp;#39; xss@(x:xs) n l | n == 0 = [[]]&lt;br /&gt;                     | l == n = [xss]&lt;br /&gt;                     | otherwise = (map (x:) $ comb&amp;#39; xs (n-1) (l-1)) ++ (comb&amp;#39; xs n (l-1))&lt;br /&gt;comb&amp;#39; [] _ _ = [[]]&lt;/pre&gt;
&lt;/blockquote&gt;&lt;p&gt;

And powerset is easy as:

&lt;blockquote&gt;
&lt;pre&gt;powerset xs = powerset&amp;#39; xs (length xs)&lt;br /&gt;powerset&amp;#39; xs l = if l &amp;lt; minLength&lt;br /&gt;                    then []&lt;br /&gt;                    else (combinations xs l) ++ (powerset&amp;#39; xs (l-1))&lt;/pre&gt;&lt;p&gt;

minLength = 3
&lt;/p&gt;&lt;/blockquote&gt;

We can now remove out the lines with &lt;tt&gt;sortBy&lt;/tt&gt; and &lt;tt&gt;filter longEnough&lt;/tt&gt;,
as the new definition already presents the items in the right order.


&lt;p&gt;
Does this make it any faster?  Apparently not:  as I guessed, powerset is not the
hotspot.  I guess that the problem is the repeated lookups in the Data.Map — any
suggestions on how to profile the Haskell code, and better algorithms to deal with it?
&lt;/p&gt; &lt;/p&gt;    &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/more-countdown-laziness-scheme-and-german-frogs.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900fa9680035a0002?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">countdown</category> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">scheme</category>   
        </item> 
 
        <item>
            <title>Schwartzian transform in Haskell</title>
            <link>http://osfameron.vox.com/library/post/schwartzian-transform-in-haskell.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/schwartzian-transform-in-haskell.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/schwartzian-transform-in-haskell.html?_c=feed-rss-full</guid> 
            <pubDate>Wed, 18 Jun 2008 22:53:28 +0100</pubDate>         
            
            <description>    &lt;p&gt;
In the last post, I mentioned that we might be able to improve the performance
of our sort using a 
&amp;quot;&lt;a&gt;http://en.wikipedia.org/wiki/Schwartzian_transform&lt;/a&gt;&amp;quot;.

&lt;/p&gt;&lt;p&gt;
This basically involves precaching the expensive calculation (in this case, &lt;tt&gt;length&lt;/tt&gt;),
sorting by the cached value, then taking just the original values.

&lt;/p&gt;&lt;p&gt;
Let&amp;#39;s test with a list of words:

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;words &amp;quot;If on a winter&amp;#39;s night a traveller&amp;quot;&lt;/pre&gt;
&lt;/blockquote&gt;


&lt;p&gt;
So instead of the original &lt;tt&gt;sortBy (flip $ comparing length)&lt;/tt&gt;, we&amp;#39;d have
something like:

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;  map fst &lt;br /&gt; . sortBy (flip $ comparing snd)  &lt;br /&gt; . map (id &amp;amp;&amp;amp;&amp;amp; length)&lt;br /&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Let&amp;#39;s read it from the bottom.  First of all we create a list of tuples using the rather
wonderful &lt;tt&gt;&amp;amp;&amp;amp;&amp;amp;&lt;/tt&gt; operator from Control.Arrow.

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;[(&amp;quot;If&amp;quot;,2),(&amp;quot;on&amp;quot;,2),(&amp;quot;a&amp;quot;,1),(&amp;quot;winter&amp;#39;s&amp;quot;,8),(&amp;quot;night&amp;quot;,5),(&amp;quot;a&amp;quot;,1),(&amp;quot;traveller&amp;quot;,9)]&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Then we sort comparing the &lt;em&gt;new&lt;/em&gt; second field of this tuple.

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;[(&amp;quot;traveller&amp;quot;,9),(&amp;quot;winter&amp;#39;s&amp;quot;,8),(&amp;quot;night&amp;quot;,5),(&amp;quot;If&amp;quot;,2),(&amp;quot;on&amp;quot;,2),(&amp;quot;a&amp;quot;,1),(&amp;quot;a&amp;quot;,1)]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;
Finally we map again, getting just the first element of the tuple.
&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;[&amp;quot;traveller&amp;quot;,&amp;quot;winter&amp;#39;s&amp;quot;,&amp;quot;night&amp;quot;,&amp;quot;If&amp;quot;,&amp;quot;on&amp;quot;,&amp;quot;a&amp;quot;,&amp;quot;a&amp;quot;]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;
And we can easily abstract this with a new function

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;sortST cmp f = map fst&lt;br /&gt;             . sortBy (cmp snd)&lt;br /&gt;             . map (id &amp;amp;&amp;amp;&amp;amp; f)&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Now we can write:

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;sortST       comparing  length listOfWords&lt;br /&gt;sortST (flip.comparing) length listOfWords&lt;br /&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
This is very similar to the sortBy syntax, except that we&amp;#39;ve separated out the &amp;quot;comparing&amp;quot;
from the &amp;quot;length&amp;quot; clause, in order to compose the two separately for the new transformation.
&lt;/p&gt;     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/schwartzian-transform-in-haskell.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900fa967f97ec0002?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">perl</category> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category>   
        </item> 
 
        <item>
            <title>Countdown words game solver in Haskell</title>
            <link>http://osfameron.vox.com/library/post/countdown-words-game-solver-in-haskell.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/countdown-words-game-solver-in-haskell.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/countdown-words-game-solver-in-haskell.html?_c=feed-rss-full</guid> 
            <pubDate>Wed, 18 Jun 2008 13:02:12 +0100</pubDate>         
            
            <description>    &lt;p&gt;
Will on #geekup has been working on a 
&lt;a href=&quot;http://www.channel4.com/entertainment/tv/microsites/C/countdown/index.html&quot;&gt;Countdown&lt;/a&gt;
&lt;a href=&quot;http://countdown.willboyce.com/&quot;&gt;letters and numbers game
solver&lt;/a&gt; written in Python.  I thought it&amp;#39;d be fun to try to do it in Haskell,
and started with the letters game (anagram) solver.
&lt;/p&gt;
&lt;p&gt;
Starting with a string of jumbled letters, the goal is to make the longest possible
anagram.  I remember the first time I tried to solve anagrams I jumped into the
problem without thinking and got mixed up in all kinds of complicated combinatorial
mess.  The actual answer is very simple:  let&amp;#39;s take two words which are anagrams of
each other:

    &lt;/p&gt;&lt;ul&gt;&lt;li&gt;monad&lt;/li&gt;&lt;li&gt;nomad&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;

Both of them contain the same letters, so they are identical in some form of &amp;quot;canonical
representation&amp;quot;, for example

    &lt;ul&gt;&lt;li&gt;&lt;tt&gt;{a:1, d:1, m:1, n:1, o:1}&lt;/tt&gt; -- dictionary mapping letter to number of times used&lt;/li&gt;&lt;li&gt;&lt;tt&gt;&amp;quot;admno&amp;quot;&lt;/tt&gt; -- a string with the letters sorted
    &lt;/li&gt;&lt;/ul&gt;

So we just need to consider all the subsets of the original jumbled letters in turn, and 
compare them against a map of:: &lt;tt&gt;canonical representation -&amp;gt; [list of words]&lt;/tt&gt;.

&lt;p&gt;
So for example:
&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;pmqnrdzoa&lt;br /&gt;...&lt;br /&gt;&amp;#160;m&amp;#160;n&amp;#160;d&amp;#160;oa&lt;br /&gt;...&lt;/pre&gt;&lt;/blockquote&gt;

This function is called a &lt;em&gt;powerset&lt;/em&gt;.  I&amp;#39;m lazy so I googled 
&lt;a href=&quot;http://www.haskell.org/pipermail/haskell-cafe/2003-June/004484.html&quot;&gt;a definition&lt;/a&gt;.
We want the longest words first.  The definition of powerset I found does a
&lt;em&gt;depth first search&lt;/em&gt; so it&amp;#39;s not in order of length.  What we want to do
is to work on a list like this

&lt;blockquote&gt;&lt;pre&gt;list s =&lt;br /&gt;                  sortBy (flip $ comparing length)  -- longest first&lt;br /&gt;                . nub                -- unique entries only&lt;br /&gt;                . powerset           -- all combinations of &lt;br /&gt;                . canonicalize       -- canonical (sorted) string&lt;br /&gt;                $ s&lt;/pre&gt;&lt;/blockquote&gt;

where &lt;em&gt;canonicalize&lt;/em&gt; is just &lt;tt&gt;sort . map toLower . filter isLetter&lt;/tt&gt;.

&lt;p&gt;
&lt;em&gt;comparing&lt;/em&gt; is a nice litle utility sub that makes the above effectively the
same as (\a b -&amp;gt; length a `compare` length b).  We then &lt;em&gt;flip&lt;/em&gt; it to reverse the
ordering (and this is actually a good use for flip ;-).
&lt;/p&gt;
&lt;p&gt;
Ordering by length is potentially inefficient — it checks the length of each
element twice, and unlike Perl (where a string knows its own length), a string is
just a list, so it has to descend the list to find it out.  This is easy to optimize
by precalculating the lengths, using a technique that in Perl we call the &amp;quot;Schwartzian
transform&amp;quot;, and I&amp;#39;ll probably come back to this.
&lt;/p&gt;
&lt;p&gt;
OK, so we have a list of subsets to compare, now we need to find a dictionary of
canonical representations of words.  Luckily most unixy distributions ship with
one, often &lt;tt&gt;/usr/dict/words&lt;/tt&gt;, but Ubuntu sticks is elsewhere.
&lt;/p&gt;
&lt;p&gt;
I asked on #haskell, and was told I should use a &lt;tt&gt;Data.Map&lt;/tt&gt;, Haskell&amp;#39;s
basic equivalent of a hash or associative array, but implemented using a 
Functional Programming friendly tree representation.  In actual fact,
quicksilver, mrs, and mmorrow told me the answer straight away, but let&amp;#39;s
pretend for the purpose of this post that we&amp;#39;re working it out now :-)
&lt;/p&gt;
&lt;p&gt;
Assuming I load that
module, as is common, as &lt;tt&gt;M&lt;/tt&gt;, I&amp;#39;d essentially want to call
&lt;tt&gt;M.insertWith (++)&lt;/tt&gt; on each element.  The &lt;tt&gt;(++)&lt;/tt&gt; is the
concatenation operator, and it&amp;#39;s the right thing to use because the
dictionary is mapping &lt;tt&gt;String -&amp;gt; [String]&lt;/tt&gt;, for example

&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;fromList [(&amp;quot;admno&amp;quot;, [&amp;quot;nomad&amp;quot;,&amp;quot;monad&amp;quot;,&amp;quot;Damon&amp;quot;]),...]&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;em&gt;insertWith&lt;/em&gt; returns a new copy of the Map each time.  It&amp;#39;s like an accumulator
which gradually takes on the entries from the list of words.  And whenever we think
about accumulators, we can think about &lt;em&gt;fold&lt;/em&gt;s.

&lt;blockquote&gt;
&lt;pre&gt;foldl&amp;#39; (\m x -&amp;gt; M.insertWith (++) (canonicalize x) [x] m) mempty listOfWords&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;em&gt;mempty&lt;/em&gt; is shorthand here for &amp;quot;an empty Data.Map&amp;quot;.  But we can go one better as
apparently fold/insertWith is so common that there is a shorthand, &lt;em&gt;fromListWith&lt;/em&gt;!

&lt;blockquote&gt;
&lt;pre&gt;fromListWith (++) . map (canonicalize &amp;amp;&amp;amp;&amp;amp; return)&lt;/pre&gt;
&lt;/blockquote&gt;
Woah!  That&amp;#39;s quite compact, and I just introduced some new syntax too:  The
&lt;tt&gt;&amp;amp;&amp;amp;&amp;amp;&lt;/tt&gt; is basically saying &amp;quot;let&amp;#39;s make a tuple with
the result of calling these 2 functions on my input!&amp;quot; so it&amp;#39;s the same as

&lt;blockquote&gt;
&lt;pre&gt;fromListWith (++) . map (\a -&amp;gt; (canonicalize a, return a))&lt;/pre&gt;
&lt;/blockquote&gt;

And &lt;em&gt;return&lt;/em&gt; just means &amp;quot;wrap this value in the appropriate Monad&amp;quot;.  So it&amp;#39;s
a scary way of saying &lt;tt&gt;[a]&lt;/tt&gt;, because we&amp;#39;re &amp;quot;in&amp;quot; the List monad.  (In the same way
that &lt;tt&gt;mempty&lt;/tt&gt; above was an empty Data.Map, because it was &amp;quot;in&amp;quot; the Map Monad.)

&lt;p&gt;
Whenever I play with Map, I get angry errors about the monomorphism restriction.
The way around that is to add an explicit type signature.  If, like me, you&amp;#39;re not
quite sure what to put there, you can add a compiler directive to quell the error,
then work out what the signature would be by calling &lt;tt&gt;:t my_function&lt;/tt&gt; from the
GHCI command line.  (You&amp;#39;ll often find afterwards that you can remove the signatures
if you wanted to, because later on the compiler has more information to work out the
types of things.  It&amp;#39;s only really &lt;em&gt;during&lt;/em&gt; incremental development that you
get the problem.

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;{-# LANGUAGE NoMonomorphismRestriction #-}&lt;br /&gt;-- (that&amp;#39;s the compiler directive, you can comment this out later)&lt;br /&gt;&lt;br /&gt;makeAnag s = do&lt;br /&gt;    d &amp;lt;- dict&lt;br /&gt;    return $ take 4 $ getAnagrams s d&lt;br /&gt;&lt;br /&gt;dict = do file &amp;lt;- readFile &amp;quot;/etc/dictionaries-common/words&amp;quot;&lt;br /&gt;          return $ mkdict $ lines file&lt;br /&gt;&lt;br /&gt;mkdict :: [String] -&amp;gt; M.Map String [String]&lt;br /&gt;mkdict = M.fromListWith (++) . map (canonicalize &amp;amp;&amp;amp;&amp;amp; return) . filter longEnough&lt;br /&gt;&lt;br /&gt;longEnough = (&amp;gt;=3) . length&lt;/pre&gt;
&lt;/blockquote&gt;

As you can see, for all the perceived difficulty of doing IO in a pure language
like Haskell, it doesn&amp;#39;t seem all that hard in this simple case.  &lt;tt&gt;readFile&lt;/tt&gt;
reads the file, and &lt;tt&gt;lines&lt;/tt&gt; splits it into an array of lines.

&lt;p&gt;
The final thing is to check each powerset against the dictionary.
To extract the value, we use &lt;tt&gt;M.lookup&lt;/tt&gt;.  This function &lt;tt&gt;fail&lt;/tt&gt;s if it
can&amp;#39;t find a value.  So we could do
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;For each powerset in the list
&lt;/li&gt;&lt;li&gt;Check if it&amp;#39;s present
&lt;/li&gt;&lt;li&gt;And add it to the list if so
&lt;/li&gt;&lt;/ul&gt;

Which of course we could do with the &lt;tt&gt;Maybe&lt;/tt&gt; type and a &lt;tt&gt;filter&lt;/tt&gt;.
But we want a list, and in the List type, failure is represented by an empty list
&lt;tt&gt;[]&lt;/tt&gt;.  So we can just map and we&amp;#39;d get something like:

&lt;blockquote&gt;&lt;pre&gt;[ [&amp;quot;anagram&amp;quot;], [], [], [&amp;quot;anagram 1&amp;quot;, &amp;quot;anagram 2&amp;quot;], [] ]&lt;/pre&gt;&lt;/blockquote&gt;

With an empty list for each failure.  We can use concatMap to join these together.  So it&amp;#39;s:

&lt;blockquote&gt;&lt;pre&gt;concatMap (\v -&amp;gt; M.lookup v dict) listOfPowersets&lt;/pre&gt;&lt;/blockquote&gt;

Though that actually returns:

&lt;blockquote&gt;&lt;pre&gt;[ [&amp;quot;anagram&amp;quot;], [&amp;quot;anagram 1&amp;quot;, &amp;quot;anagram 2&amp;quot;], ]&lt;/pre&gt;&lt;/blockquote&gt;

which I hadn&amp;#39;t expected.  (&lt;tt&gt;M.lookup&lt;/tt&gt; returned a list like &lt;tt&gt;[&amp;quot;anagram
1&amp;quot;, &amp;quot;anagram 2&amp;quot;]&lt;/tt&gt;.  
Quite literally it &lt;tt&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/tt&gt;ed it, which in List context means it
actually passed &lt;tt&gt;[[&amp;quot;anagram 1&amp;quot;, &amp;quot;anagram 2&amp;quot;]]&lt;/tt&gt;, which is why the list isn&amp;#39;t completely
flattened by concatMap.  I get around this by using &lt;tt&gt;join&lt;/tt&gt;.  This is another of those
monadic functions: in List context it does exactly what we want here, flattening this list.

&lt;blockquote&gt;
&lt;pre&gt;getAnagrams s d = join &lt;br /&gt;                . concatMap (flip M.lookup $ d)&lt;br /&gt;                $ filter longEnough  -- 3 or more letters&lt;br /&gt;                . sortBy (flip $ comparing length)  -- longest first&lt;br /&gt;                . nub                -- unique entries only&lt;br /&gt;                . powerset           -- all combinations of &lt;br /&gt;                . canonicalize       -- canonical (sorted) string&lt;br /&gt;                $ s&lt;/pre&gt;&lt;/blockquote&gt;
                
You can look at the final &lt;a href=&quot;http://greenokapi.net/svn/code/scratch/countdown.hs&quot;&gt;Haskell Countdown code&lt;/a&gt;.  I&amp;#39;ll look at optimizing the sort and the powersets soon, any comments on
other improvements (including better algorithms) very welcome.  (Sorry, comments require
Vox signup...)&lt;br /&gt;&lt;/p&gt;    &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/countdown-words-game-solver-in-haskell.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900fa968015b70003?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">countdown</category> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category>   
        </item> 
 
        <item>
            <title>Monads in Perl (take 1)</title>
            <link>http://osfameron.vox.com/library/post/monads-in-perl-take-1.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monads-in-perl-take-1.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monads-in-perl-take-1.html?_c=feed-rss-full</guid> 
            <pubDate>Thu, 12 Jun 2008 23:27:26 +0100</pubDate>         
            
            <description>    



&lt;p&gt;
I&amp;#39;ve been away for a while from Haskell so I thought I should do some revision
and really get my head around Monads.  While I plodded through the wonderful
&lt;a href=&quot;http://www.haskell.org/all_about_monads/html/meet.html&quot;&gt;&amp;quot;meet the monads&amp;quot; tutorial&lt;/a&gt;, I decided that the best way to learn would be to do.  By implementing Monads in Perl.
I&amp;#39;d highly recommend trying to implement monads in Your Favourite Language, if it
supports lambdas.  Perl has &lt;a href=&quot;http://sleepingsquirrel.org/monads/monads.html&quot;&gt; already been done by
Greg Buchholz&lt;/a&gt; and rather nicely too, but there&amp;#39;s no Monad library on CPAN
so I thought it would be worth a try.
&lt;/p&gt;

&lt;p&gt;
First of all, the question of how to model &amp;quot;types&amp;quot; is easily resolved.  We bless each
monad into the &lt;tt&gt;Monad&lt;/tt&gt; class or a subclass.  These can then have methods for
&lt;tt&gt;bind&lt;/tt&gt; and &lt;tt&gt;return&lt;/tt&gt; etc.
&lt;/p&gt;

&lt;p&gt;
Now I do like the haskell &lt;tt&gt;&amp;gt;&amp;gt;&lt;/tt&gt; and by a stroke of good fortune, Perl allows
us to overload that symbol too.

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;use overload &amp;#39;&amp;gt;&amp;gt;&amp;#39;   =&amp;gt; &amp;#39;Bind&amp;#39;;&lt;/pre&gt;
&lt;/blockquote&gt;


&lt;p&gt;
I use the string &lt;tt&gt;&amp;#39;Bind&amp;#39;&lt;/tt&gt; rather than the reference &lt;tt&gt;\&amp;amp;Bind&lt;/tt&gt;, so that
the subclasses can easily override it.
&lt;/p&gt;

&lt;p&gt;
Some default bind methods in &lt;tt&gt;Monad.pm&lt;/tt&gt; and &lt;tt&gt;Monad::Maybe&lt;/tt&gt; etc.,
&lt;a href=&quot;http://greenokapi.net/svn/code/scratch/Monads/&quot;&gt;available here&lt;/a&gt; and
we have some simple examples like this one (in test.pl):

&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;my $result = &lt;br /&gt;      (Writer 2) &amp;gt;&amp;gt;&lt;br /&gt;      L { my $x = shift; (Writer $x*2, &amp;quot;Doubled. &amp;quot;) &amp;gt;&amp;gt;&lt;br /&gt;      L { my $y = shift; (Writer $y+1, &amp;quot;Plus 1. &amp;quot;)  &amp;gt;&amp;gt;&lt;br /&gt;      L { my $z = shift; (Writer $z*3, &amp;quot;Tripled $z. &amp;quot;) &lt;br /&gt;      }}};&lt;/pre&gt;
&lt;/blockquote&gt;


&lt;p&gt;
Woot!  OK, that&amp;#39;s not entirely beautiful, but it&amp;#39;s been slightly improved by the
overloading of &lt;tt&gt;&amp;gt;&amp;gt;&lt;/tt&gt;.
&lt;/p&gt;

&lt;p&gt;
The &lt;tt&gt;L&lt;/tt&gt; lambda generator is also there for readability.  It&amp;#39;s basically defined as

&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;sub L (&amp;amp;) { shift }&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;

i.e. it&amp;#39;s an identity function, but it&amp;#39;s an L (like lambda) and to my mind, lined up on 
the left, it looks pleasingly like &amp;quot;and then&amp;quot;.


&lt;h2&gt;Nests&lt;/h2&gt;

&lt;p&gt;
This didn&amp;#39;t just fall straight out of the text editor into fully working code, of course.
A blow-by-blow account of me getting confused wouldn&amp;#39;t be especially interesting, but one
big &amp;quot;aha&amp;quot; moment is worth pointing out.  I realised that I was thinking of monads as being
a chain of lambdas, each one passing control to the next, like OO chaining:  
&lt;/p&gt;
    
    
    

    
    
    

    
    
    

    
    
    

    
    
    
&lt;div at:enclosure=&quot;asset&quot; at:xid=&quot;6a00c225240a9af21900fae8c2562a000b&quot; at:format=&quot;medium&quot; at:align=&quot;center&quot;
    class=&quot;enclosure enclosure-center enclosure-medium photo-enclosure&quot; 
     style=&quot;text-align: center;&quot;&gt;
&lt;div class=&quot;enclosure-inner&quot;
    
        style=&quot;padding: 9px; border: 1px solid; width: px; margin: 10px auto;&quot;
    &gt;
    &lt;div class=&quot;enclosure-list&quot;&gt;
        &lt;div class=&quot;enclosure-item photo-asset last&quot;&gt;
    
            &lt;div class=&quot;enclosure-image&quot;&gt;
        
                &lt;a href=&quot;http://osfameron.vox.com/library/photo/6a00c225240a9af21900fae8c2562a000b.html&quot;&gt;&lt;img src=&quot;http://a2.vox.com/6a00c225240a9af21900fae8c2562a000b-200pi&quot; alt=&quot;Chain of lambdas?&quot; title=&quot;Chain of lambdas?&quot; /&gt;&lt;/a&gt;
        
            &lt;/div&gt;
            &lt;div class=&quot;enclosure-meta&quot;&gt;
                &lt;div class=&quot;enclosure-asset-name&quot;&gt;&lt;a href=&quot;http://osfameron.vox.com/library/photo/6a00c225240a9af21900fae8c2562a000b.html&quot; title=&quot;Chain of lambdas?&quot;&gt;Chain of lambdas?&lt;/a&gt;&lt;/div&gt;
            &lt;/div&gt;
    
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;!-- end enclosure --&gt;




&amp;#160;

&lt;p&gt;
But that doesn&amp;#39;t work, as of course then the &lt;tt&gt;$x&lt;/tt&gt;, &lt;tt&gt;$y&lt;/tt&gt;,
&lt;tt&gt;$z&lt;/tt&gt; of each scope would be separate, whereas in fact, in &amp;quot;later&amp;quot; sections, you
can refer to &lt;tt&gt;$x&lt;/tt&gt; too.  This implies that the model is more like a nest of lambdas:
&lt;/p&gt;
    
    
    

    
    
    

    
    
    

    
    
    

    
    
    
&lt;div at:enclosure=&quot;asset&quot; at:xid=&quot;6a00c225240a9af21900fa967dc4a50002&quot; at:format=&quot;medium&quot; at:align=&quot;center&quot;
    class=&quot;enclosure enclosure-center enclosure-medium photo-enclosure&quot; 
     style=&quot;text-align: center;&quot;&gt;
&lt;div class=&quot;enclosure-inner&quot;
    
        style=&quot;padding: 9px; border: 1px solid; width: px; margin: 10px auto;&quot;
    &gt;
    &lt;div class=&quot;enclosure-list&quot;&gt;
        &lt;div class=&quot;enclosure-item photo-asset last&quot;&gt;
    
            &lt;div class=&quot;enclosure-image&quot;&gt;
        
                &lt;a href=&quot;http://osfameron.vox.com/library/photo/6a00c225240a9af21900fa967dc4a50002.html&quot;&gt;&lt;img src=&quot;http://a5.vox.com/6a00c225240a9af21900fa967dc4a50002-200pi&quot; alt=&quot;Nest of lambdas&quot; title=&quot;Nest of lambdas&quot; /&gt;&lt;/a&gt;
        
            &lt;/div&gt;
            &lt;div class=&quot;enclosure-meta&quot;&gt;
                &lt;div class=&quot;enclosure-asset-name&quot;&gt;&lt;a href=&quot;http://osfameron.vox.com/library/photo/6a00c225240a9af21900fa967dc4a50002.html&quot; title=&quot;Nest of lambdas&quot;&gt;Nest of lambdas&lt;/a&gt;&lt;/div&gt;
            &lt;/div&gt;
    
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;!-- end enclosure --&gt;




&amp;#160;

&lt;p&gt;
This is made fairly clear in the Perl above, with its delimited braces, if you look at
where the closing &amp;quot;&lt;tt&gt;}&lt;/tt&gt;&amp;quot; are, and which opening &amp;quot;&lt;tt&gt;{&lt;/tt&gt;&amp;quot; they match up with.
&lt;/p&gt;

&lt;p&gt;
This is an interesting mind shift, and one that I still haven&amp;#39;t really fully grasped, as
I&amp;#39;ll demonstrate a bit later.
&lt;/p&gt;

&lt;h2&gt; Polymorphic functions on monads &lt;/h2&gt;

&lt;p&gt;
In Haskell, you can call &amp;quot;&lt;tt&gt;return&lt;/tt&gt;&amp;quot; in a monadic block to &amp;quot;lift&amp;quot; a value to 
the appropriate monad.  Similarly, you can call &amp;quot;&lt;tt&gt;fail&lt;/tt&gt;&amp;quot;, and the function
will fail in the right way (returning &lt;tt&gt;Nothing&lt;/tt&gt; in a Maybe, throwing an error
in IO).  This is a function call, not a method, so how does it know which monad to
behave as?
&lt;/p&gt;

&lt;p&gt;
Of course Haskell does this with its strong inferencing typechecker.  The
compiler &amp;quot;knows&amp;quot; that we are in Maybe, so &amp;quot;fail&amp;quot; will be &lt;tt&gt;fail :: Maybe&lt;/tt&gt;.
&lt;/p&gt;

&lt;p&gt;
Perl on the other hand doesn&amp;#39;t have a strong type-inferencing compiler...
Right now I&amp;#39;m doing some shonky magic with &lt;tt&gt;caller()&lt;/tt&gt; that works in this
very simple test case (and I believe &lt;em&gt;only&lt;/em&gt; in this test case).  I think I
could just simplify things and set a dynamic variable &amp;quot;$Monad::current_monad&amp;quot;
on the first occurrence of &lt;tt&gt;Bind&lt;/tt&gt;.  Yeah, global variables, yuck.  The
final alternative that occurs to me would be to run the whole thing in a Reader
monad which just passes the name of the monad... but I&amp;#39;m fairly sure that&amp;#39;s
slightly insane.
&lt;/p&gt;

&lt;h2&gt; So what can it do right now? &lt;/h2&gt;

&lt;p&gt;
The &lt;a href=&quot;http://greenokapi.net/svn/code/scratch/Monads/test.pl&quot;&gt;test script&lt;/a&gt; shows
the current capabilities.  As of r246, I have Writer, Maybe, and List implemented (the
Monad superclass is effectively Identity).  
&lt;/p&gt;

&lt;p&gt;
I think Maybe is very useful - with some wrapper functions that raise Perl functions to
monadic ones using a variety of strategies (fail on undef/0/die etc.) it could be a useful
addition to the toolbox, simplifying a nested set of &lt;tt&gt;if&lt;/tt&gt; checks.
&lt;/p&gt;

&lt;p&gt;
The List monad already does list comprehensions, albeit with a rather yucky syntax.
Which is of course the big problem, &amp;#39;cos Perl programmers (and this statement may surprise
non Perl programmers :-) are often obsessive about syntax.
&lt;/p&gt;

&lt;h2&gt; Making it look pretty &lt;/h2&gt;

&lt;p&gt;
OK, so we already added a bit of sugar with the &lt;tt&gt;&amp;gt;&amp;gt;&lt;/tt&gt; overloading, and the
&lt;tt&gt;L&lt;/tt&gt; function for lambda generators, but it&amp;#39;s still rather ugly with the mix of
Perlish argument unpacking (&lt;tt&gt;my $x = shift&lt;/tt&gt;), scope delimiters (&lt;tt&gt;}}}&lt;/tt&gt;) etc.
&lt;/p&gt;

&lt;h3&gt; Source filters! &lt;/h3&gt;

&lt;p&gt;
The original &lt;a href=&quot;http://sleepingsquirrel.org/monads/monads.html&quot;&gt;Perl monad
tutorial&lt;/a&gt; used a source filter to give a monadic Do notation.  It&amp;#39;s a fairly
nice one as they go, but I don&amp;#39;t really want to treat my program as a string if
I can help it, so let&amp;#39;s look at some other techniques first!
&lt;/p&gt;

&lt;h3&gt; &lt;tt&gt;Devel::Declare&lt;/tt&gt; &lt;/h3&gt;

&lt;p&gt;
Matt Trout has been working on some crazy parsing magic in
&lt;tt&gt;&lt;a href=&quot;http://search.cpan.org/%7Emstrout/Devel-Declare/&quot;&gt;Devel::Declare&lt;/a&gt;&lt;/tt&gt;.
This isn&amp;#39;t a source filter, but (I think) hooks into Perl&amp;#39;s parser to change the way that
subroutine declarations are parsed.  It&amp;#39;d designed to give us parameter
unpacking, so that we could substitute:
&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;L {my $x = shift; .... }&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;
with:
&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;L ($x) { .... }&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;
In the current version this doesn&amp;#39;t work (you can define &lt;tt&gt;L&lt;/tt&gt; like that
easily, but the overloaded &lt;tt&gt;&amp;gt;&amp;gt;&lt;/tt&gt; evidences a minor parsing bug
(you&amp;#39;d have to put the expression between parentheses to get the precedence
right, which loses the syntactic advantage we gain).
&lt;/p&gt;

&lt;p&gt;
Still, hopefully will be fixed in a future release.
&lt;/p&gt;

&lt;h3&gt; Generators &lt;/h3&gt;

&lt;p&gt;
&amp;quot;Valued Lessons&amp;quot; has a beautiful post on &lt;a href=&quot;http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html&quot;&gt;Monads
in Python (with nice syntax!)&lt;/a&gt;.  The parenthesis is not hyperbole: the post describes
a monadic do block which looks about as pretty as Haskell&amp;#39;s, but which works in a different
way.  We spell &amp;#39;bind&amp;#39; (Haskell&amp;#39;s &lt;tt&gt;&amp;lt;-&lt;/tt&gt;) as &amp;#39;&lt;tt&gt;yield&lt;/tt&gt;&amp;#39;.  So a control sub
calls the &amp;#39;do&amp;#39; block, gets out monadic values one by one as they are &lt;tt&gt;yield&lt;/tt&gt;ed back,
and deals with the nitty gritty of &lt;tt&gt;bind&lt;/tt&gt;ing them to the rest of the generator.
&lt;/p&gt;

&lt;p&gt;
It took quite a while to understand the Python code: in fact I&amp;#39;m not sure I understand
it fully, I really don&amp;#39;t buy into the &amp;quot;Python is so easy to read&amp;quot; meme, and certainly
the &amp;quot;&lt;tt&gt;@whatever&lt;/tt&gt;&amp;quot; syntax, which seems to be &amp;#39;decorators&amp;#39; that modify the subroutine
that follows them, are rather confusing at first.  But it&amp;#39;s quite impressive, and it took
me a while to replicate in Perl.
&lt;/p&gt;

&lt;p&gt;
First hurdle:  Perl doesn&amp;#39;t have generators.  OK, that shouldn&amp;#39;t be an issue, I thought,
because we have the &lt;a href=&quot;http://search.cpan.org/&quot;&gt;CPAN&lt;/a&gt;.  And yes, I found Brock Wilcox&amp;#39;s
&lt;tt&gt;&lt;a href=&quot;http://search.cpan.org/%7Eawwaiid/Coro-Generator&quot;&gt;Coro::Generator&lt;/a&gt;&lt;/tt&gt;.
&lt;/p&gt;

&lt;p&gt;
This doesn&amp;#39;t quite do what I want though.  The yield only works one way, so

    &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;my $x = yield (Monad 3);&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;

doesn&amp;#39;t actually bind $x to 3.  I asked Brock on IRC, and apparently this behaviour is
desired (I&amp;#39;m not quite sure why) so I forked his code to play with it :-)
Also, the coroutine restarts immediately it finishes, which is inconvenient.
Brock suggested yielding undef at the end, which is fine, I can do that from the
control sub.
(The Python version deals with finishing by throwing an exception, so perhaps
it has the same semantics?)


&lt;p&gt;
After a lot of ugly pain, I finally got this working, and we can now do:

&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;my $result = Do {&lt;br /&gt;    my $x = yield (Just 3);&lt;br /&gt;    my $y = yield (Nothing);&lt;br /&gt;    my $z = yield (Just 5);&lt;br /&gt;    warn &amp;quot;x=$x, y=$y, z=$z&amp;quot;;&lt;br /&gt;    Just 6;&lt;/pre&gt;&lt;/blockquote&gt;


&lt;p&gt;
Why the pain?  Failing to understand coroutines while trying to use them to implement monads
(which I understand only very slightly) was a bad start.  I found myself using the Do function
to repeatedly take a value from the generator and bind it with the next value (rather than
letting the monadic bind deal with those details).  And even when I&amp;#39;d realised that the
sub that I needed to bind was a lambda that would abstract the details of invoking the coroutine,
I still ended up flailing around more or less at random till I finally got it working.
&lt;/p&gt;

&lt;p&gt;
The current code is ugly (declared inline in &lt;tt&gt;test.pl&lt;/tt&gt; rather than modularized) but
the result is pleasantly magical and readable.
&lt;/p&gt;

&lt;p&gt;
Props of course to Python for having powerful techniques like &lt;tt&gt;yield&lt;/tt&gt; and decorators 
in core!
&lt;/p&gt;

&lt;h3&gt; Hold the champagne &lt;/h3&gt;

&lt;p&gt;
Of course the final test example, in the List monad doesn&amp;#39;t work.  Why?  The List monad&amp;#39;s
bind strategy is to call the function on every element of the list, so the coroutine will get
called repeatedly.  And every time it&amp;#39;s called, the execution pointer will move on.
&lt;/p&gt;

&lt;p&gt;
I wonder whether the Python version has the same problem?  I looked again at
the Coro modules on CPAN, and noted that they are advertised as being able to
implement &amp;quot;(non-clonable) continuations&amp;quot;.  I think this is the problem: I want to be
able to take the point at which the next Bind will be called, and call exactly that same
point multiple times (for the List monad).  I asked various people including Brock again,
and Scott Walters (the authors of &lt;a href=&quot;http://continuity.tlt42.org/&quot;&gt;Continuity, a
continuation-based web application framework in Perl&lt;/a&gt;) and got the answer that Perl
really doesn&amp;#39;t do proper continuations.  (As far as I understood it, they&amp;#39;re more or
less practically impossible, due to the way Perl models its execution context).
&lt;/p&gt;

&lt;p&gt;
So, unless I&amp;#39;ve misunderstood (and please let me know if I have!) this technique is
limited to monads that only call the bound function once (e.g. most of them except List).
That&amp;#39;s a shame though, as the List comprehension semantics would be lovely to express
in a monadic do block.
&lt;/p&gt;

&lt;h3&gt; Meta continuations &lt;/h3&gt;

&lt;p&gt;
The Valued Lesson post &lt;em&gt;does&lt;/em&gt; implement continuations monadically... Could we do that
and then implement monadic do using these monadic continuations?  I think the answer might be
&amp;quot;Yes but my brain would explode trying to implement it&amp;quot;.
&lt;/p&gt;

&lt;h3&gt; Plan &lt;tt&gt;B&lt;/tt&gt; &lt;/h3&gt;

&lt;p&gt;
I think that the most sensible method may be to take the contents of the monadic do
block and use the &lt;tt&gt;B::&lt;/tt&gt; modules to convert them from what &lt;em&gt;looks like&lt;/em&gt;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;my $x = bind ...;&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt; to 
&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;... &amp;gt;&amp;gt; sub { my $x = shift;&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;.  Which
is pretty much the approach of Greg Buchholz&amp;#39;s source filter.  But I think a parse
tree transformation may be more elegant.  (This said, I don&amp;#39;t know the Perl source
or understand the opcodes, so it may just be slightly crazy).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;Some &lt;a href=&quot;http://www.reddit.com/r/programming/info/6n5wt/comments/&quot;&gt;discussion on reddit&lt;/a&gt;, as Vox still doesn&amp;#39;t support OpenID&lt;br /&gt;

&lt;/p&gt;    &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monads-in-perl-take-1.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900fad690d9cd0004?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">perl</category> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monads</category> 
            <category domain="http://osfameron.vox.com/tags/">lambdacamel</category>    
        </item> 
 
        <item>
            <title>F# talk in Liverpool</title>
            <link>http://osfameron.vox.com/library/post/f-talk-in-liverpool.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/f-talk-in-liverpool.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/f-talk-in-liverpool.html?_c=feed-rss-full</guid> 
            <pubDate>Fri, 16 May 2008 08:35:07 +0100</pubDate>         
            
            <description>    &lt;p&gt;
I&amp;#39;d been out of Liverpool for 3 years or so, and I completely missed &lt;a href=&quot;http://geekup.org/&quot;&gt;GeekUp&lt;/a&gt;: a loosely
affiliated, grassroots tech meetup society in the North West.  The Liverpool branch is
pretty active, and linked with various other groups, such as the 
&lt;a href=&quot;http://liverpool.usersof.net/&quot;&gt;DotNet user group&lt;/a&gt;,
where &lt;a href=&quot;http://blog.cwa.me.uk/&quot;&gt;Chris Alcock&lt;/a&gt; gave a very interesting
&lt;a href=&quot;http://upcoming.yahoo.com/event/547197/&quot;&gt;talk on F#&lt;/a&gt;.

&lt;/p&gt;&lt;p&gt;
Not sure what the Dot Net programmers made of it, there were some questions afterwards
amounting to &amp;quot;What&amp;#39;s the point?  Are academics going to use it?&amp;quot; :-)  Which I thought
was amusing as I was looking at it from the perspective of a Haskell newbie, thinking
a) that&amp;#39;s cool, b) it&amp;#39;s simpler than Haskell, c) it plugs into the .Net libraries and
development environment, and had concluded that it could (possibly) become a massive hit
in real-world programming too...

&lt;/p&gt;&lt;p&gt;
Some notes, mainly comparisons with Haskell:

&lt;/p&gt;&lt;ul&gt;&lt;li&gt; The &lt;tt&gt;#light&lt;/tt&gt; pragma adds syntactic sugar, very much like the
Haskell &lt;tt&gt;do&lt;/tt&gt; notation.  (No need for open/close/statement delimiters,
whitespace significant, skip &lt;tt&gt;in&lt;/tt&gt; off &lt;tt&gt;let&lt;/tt&gt; statements)
&lt;/li&gt;&lt;li&gt; The REPL is multiline by default (dons on #haskell noted that ghci
supports this with &lt;tt&gt;:{&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt; Functions aren&amp;#39;t recursive by default and have to be introduced as such (&lt;tt&gt;let &lt;em&gt;rec&lt;/em&gt; factorial = ...&lt;/tt&gt;)
&lt;/li&gt;&lt;li&gt; &lt;tt&gt;List&lt;/tt&gt;s aren&amp;#39;t lazy, but there&amp;#39;s a &lt;em&gt;separate&lt;/em&gt; datatype called &lt;tt&gt;Seq&lt;/tt&gt; which is.
&lt;/li&gt;&lt;li&gt; You can use &lt;tt&gt;yield&lt;/tt&gt; in a function to define lazy sequences.
&lt;/li&gt;&lt;li&gt; Like Ocaml, F# supports &lt;tt&gt;mutable&lt;/tt&gt; data, though the default is pure data.
&lt;/li&gt;&lt;li&gt; It also supports reference types - I&amp;#39;m not sure I understand what these
are for in a functional programming language, or if they&amp;#39;re just for updating,
then how they&amp;#39;re different from plain old mutable data.  The example Chris gave
was the classic closure example of a counter function.
&lt;/li&gt;&lt;li&gt;
    
    
    










    
    
    









&lt;div at:enclosure=&quot;asset&quot; at:xid=&quot;6a00c225240a9af21900fa9675da910003&quot; at:format=&quot;small&quot; at:align=&quot;right&quot;
    class=&quot;enclosure enclosure-right enclosure-small book-enclosure&quot; 
     style=&quot;text-align: center; float: right;&quot;&gt;
&lt;div class=&quot;enclosure-inner&quot;
    
        style=&quot;padding: 9px; border: 1px solid; width: px; margin: 0 0 20px 20px;&quot;
    &gt;
    &lt;div class=&quot;enclosure-list&quot;&gt;
        &lt;div class=&quot;enclosure-item book-asset last&quot;&gt;
    
            &lt;div class=&quot;enclosure-image&quot;&gt;
        
                &lt;a href=&quot;http://osfameron.vox.com/library/book/6a00c225240a9af21900fa9675da910003.html&quot;&gt;&lt;img src=&quot;http://a1.vox.com/6a00c225240a9af21900fa9675da910003-120pi&quot; alt=&quot;Expert F# Hardback (Expert&#39;s Voice in .Net)&quot; title=&quot;Expert F# Hardback (Expert&#39;s Voice in .Net)&quot; /&gt;&lt;/a&gt;
        
            &lt;/div&gt;
            &lt;div class=&quot;enclosure-meta&quot;&gt;
                &lt;div class=&quot;enclosure-asset-name&quot;&gt;&lt;a href=&quot;http://osfameron.vox.com/library/book/6a00c225240a9af21900fa9675da910003.html&quot; title=&quot;Expert F# Hardback (Expert&#39;s Voice in .Net)&quot;&gt;Expert F# Hardback (Expert&#39;s Voice in .Net)&lt;/a&gt;&lt;/div&gt;
            &lt;/div&gt;
    
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;!-- end enclosure --&gt;

 The examples he made of pipelining with &lt;tt&gt;|&amp;gt;&lt;/tt&gt; and &lt;tt&gt;&amp;gt;&amp;gt;&lt;/tt&gt;
looked very much Haskellish monads (especially in a &lt;tt&gt;#light&lt;/tt&gt; style
block).  I quickly leafed through Chris&amp;#39;s copy of
till I found the
section on monads.  They&amp;#39;re called &amp;quot;Workflows&amp;quot;, because that&amp;#39;s less scary than
Monads.  They&amp;#39;re also largely transparent, which on one hand is nice, as
there&amp;#39;s none of the painful and ugly &amp;quot;lifting&amp;quot; of values to the appropriate
monad.  (On the other, it means that you can&amp;#39;t easily separate action and
non-action code).  
&lt;/li&gt;&lt;li&gt; This of course means that you don&amp;#39;t get some of the benefits of FP&amp;#39;s
purity.  &lt;a href=&quot;http://blog.martinowen.net/&quot;&gt;Martin Owen&lt;/a&gt;, who is keen
on Erlang and its capacity for massively scalable, high performance networking,
also pointed out that allowing mutability means that you can&amp;#39;t guarantee that
the application is threadsafe, and is the wrong default as we&amp;#39;re coming up against
multicore programming.
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
All in all, it was a very interesting talk, and I&amp;#39;m looking forward to playing
with F#.  I apt-got &lt;a href=&quot;http://www.mono-project.com/Main_Page&quot;&gt;Mono&lt;/a&gt;, and
promptly failed to install F# on it, as the provided install.sh script whined about
something to do with &lt;tt&gt;gac&lt;/tt&gt; and &lt;tt&gt;aot&lt;/tt&gt;.  Ah well, perhaps that&amp;#39;s a good
excuse to boot up into Windows...
&lt;/p&gt;     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/f-talk-in-liverpool.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900fad6884a750004?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">dotnet</category> 
            <category domain="http://osfameron.vox.com/tags/">mono</category> 
            <category domain="http://osfameron.vox.com/tags/">liverpool</category> 
            <category domain="http://osfameron.vox.com/tags/">geekup</category> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">f#</category> 
            <category domain="http://osfameron.vox.com/tags/">ocaml</category> 
            <category domain="http://osfameron.vox.com/tags/">erlang</category> 
            <category domain="http://osfameron.vox.com/tags/">monads</category>    
        </item> 
 
        <item>
            <title>Monad Wars - code online</title>
            <link>http://osfameron.vox.com/library/post/monad-wars---code-online.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monad-wars---code-online.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monad-wars---code-online.html?_c=feed-rss-full</guid> 
            <pubDate>Wed, 28 Nov 2007 09:19:59 +0000</pubDate>         
            
            <description>    &lt;p&gt;Chessguy pointed out that it&amp;#39;s currently hard to play along with the monad wars code.&lt;/p&gt;
&lt;p&gt;It would be nice for the posts to be “literate haskell”, where sections preceded by “&lt;tt&gt;&amp;gt;&lt;/tt&gt;“
characters are valid Haskell. The idea is great - that you can mix
sections of introduction and description with sections of actual code,
ending up with an article that is also executable code! Which is very
much the style of these posts, but right now I&amp;#39;m being too lazy to go
that extra step:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;sometimes I show multiple version of the same function, (some of them might not work) &lt;/li&gt;&lt;li&gt;I tend to introduce &lt;tt&gt;import&lt;/tt&gt;s as needed but (I believe) they need to be at the top of the file &lt;/li&gt;&lt;li&gt;I don&amp;#39;t always repeat functions from earlier posts but just refer to them &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So I&amp;#39;ve posted the current source to my &lt;a href=&quot;http://greenokapi.net/svn/code/monadwars/&quot;&gt;subversion repo&lt;/a&gt;.
As you can see they&amp;#39;re currently related to the number of the
associated post, and contain different areas of functionality: this is
actually how I&amp;#39;m working on it for the moment - I&amp;#39;m hoping to put
together some of the pieces in part 5 or so (Blog Driven Development is
a rather odd way to structure your work but there you go...)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;Vincenz on #haskell convinced me that I really should try literate haskell - watch this space...&lt;/p&gt;&lt;p&gt;I&amp;#39;m now probably going to fall off the internet for a week while I move country and job.&amp;#160; I&amp;#39;ll be at the London Perl Workshop this Saturday and will talk (for a whole 5 minutes!) about Monad Wars. Maybe see you there :D&lt;/p&gt;    &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monad-wars---code-online.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900e398c1eda80002?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monadwars</category>   
        </item> 
 
        <item>
            <title>Monad Wars - 3: Command line actions</title>
            <link>http://osfameron.vox.com/library/post/monad-wars---3-command-line-actions.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monad-wars---3-command-line-actions.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monad-wars---3-command-line-actions.html?_c=feed-rss-full</guid> 
            <pubDate>Tue, 27 Nov 2007 07:52:19 +0000</pubDate>         
            
            <description>    &lt;p&gt;After the last post, we have parser actions that can recognise an
integer or an item of merchandise. Now we need to be able to process a
command, like “jet bronx” or “buy 4 lambdas”. Let&amp;#39;s start off with this
basis:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseCommand &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; parseMap commandMap&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; commandMap &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; getPrefixMap &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;buy&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;  cmdBuy  &lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;sell&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; cmdSell &lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;jet&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;  cmdJet &lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;quit&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; cmdQuit &lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;          &lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Now, what we roughly want to do is: &lt;/p&gt;&lt;ul&gt;&lt;li&gt; Tokenise the line &lt;/li&gt;&lt;li&gt; Check if the first token maps to a command &lt;/li&gt;&lt;li&gt; Check if the rest of the tokens can be handled by that command. &lt;/li&gt;&lt;li&gt; The result (if applicable) is a function that maps an original GameState into a new state. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We might come up with something like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseLine s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;let&lt;/u&gt;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;cmd&lt;span style=&quot;color: red&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt;pars&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; tokenizeLine s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  c  &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; parseCommand cmd&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  c&amp;#39; &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; c pars&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  return c&amp;#39;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;But I&amp;#39;d promised that we&amp;#39;d &lt;em&gt;check&lt;/em&gt; if the parsing worked!  Can you see any checks like that above?&lt;/p&gt;
&lt;h1&gt;Possibly Maybe&lt;/h1&gt;

&lt;p&gt;If we check the type of parseCommand, we&amp;#39;ll notice it returns a Maybe&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; parseCommand :: [Char] &lt;br /&gt;    -&amp;gt; Maybe ([String] -&amp;gt; Maybe (GameState -&amp;gt; Maybe GameState))&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;This means that the do expression starts with a Maybe (we don&amp;#39;t count the let expression) and so is &lt;em&gt;in&lt;/em&gt;
the Maybe monad. If any of the sequence fails, parseLine will return
Nothing, without us having to specify anything! This is quite cute and,
once you get used to it, rather intuitive (the definition above fell
naturally out of my text editor).&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s another example of Maybe - parsing the expressions like “buy
4 curry” or “sell 10 stm”. First of all, we notice that cmdBuy and
cmdSell both have the same form, so we&amp;#39;ll share the code in a common
parser called &lt;tt&gt;cmdMerchandise&lt;/tt&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdBuy  &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; cmdMerchandise  doBuy&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdSell &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; cmdMerchandise  doSell&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;This parser looks at the first 2 parameters, and tries to parse them respectively as an Int or an item of Merchandise.&lt;/p&gt;
&lt;p&gt;If either of the parses fails, it will magically return Nothing.&lt;/p&gt;
&lt;p&gt;If it succeeds, it will return the result of, for example &lt;tt&gt;doBuy 10 lambdas&lt;/tt&gt;.
(The result is of course a function that takes a GameState in input,
and returns a GameState that is the result of having bought 10 lambdas.
Very meta.)&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdMerchandise f &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;n&lt;span style=&quot;color: red&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt;m&lt;span style=&quot;color: red&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; n&amp;#39; &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; parseInt n&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                               m&amp;#39; &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; parseMerchandise m&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                               Just &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; f n&amp;#39; m&amp;#39;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdMerchandise &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt;       &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h1&gt;Let&amp;#39;s play&lt;/h1&gt;

&lt;p&gt;This is getting a little abstract if we can&amp;#39;t test it. Right now our
GameState record doesn&amp;#39;t have a “list of merchandise” structure, so
let&amp;#39;s keep it simple for the sake of argument and add a debug string
instead.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;data&lt;/u&gt;&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; GameState &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        turn     &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        score    &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        location &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Location&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        debug    &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; String&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;deriving&lt;/u&gt;&lt;/span&gt; Show&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;type&lt;/u&gt;&lt;/span&gt; Location &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Int&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;(and add a &lt;tt&gt;debug = ““&lt;/tt&gt; to the startState declaration.)&lt;/p&gt;
&lt;p&gt;We&amp;#39;ll make the doBuy and doSell functions just modify the debug string:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; doBuy  n m gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;     debug &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;You bought &amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;             &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;show n&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;             &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;name m&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;     &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; doSell  n m gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;     debug &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;You sold &amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;             &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;show n&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;             &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;name m&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;     &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;OK, we could factor these out as an exercise, but we&amp;#39;ll be replacing
them soon. Now, what we really want to do is to test it! I&amp;#39;ll look at
plugging this into the prompt structure next time, for now let&amp;#39;s just
create a test function. This just takes a GameState and a line, and
returns the new state if it all worked out.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; test gs s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; c &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; parseLine s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                c gs&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;We can play with this to see if it worked:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; test startState &amp;quot;sell 3 la&amp;quot;&lt;br /&gt; Just (GameState {turn = 1, score = 0, location = 0, &lt;br /&gt;                  debug = &amp;quot;You sold 3 Lambdas&amp;quot;})&lt;br /&gt; *Main&amp;gt; test startState &amp;quot;panic&amp;quot;&lt;br /&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;The other actions are similar.  We&amp;#39;ll use the record mutators &lt;tt&gt;modScore&lt;/tt&gt; and &lt;tt&gt;nextTurn&lt;/tt&gt; that we saw last time.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;-- Just a stub: We&amp;#39;ll probably want to set an &amp;quot;endflag&amp;quot; or similar.&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdQuit &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Just doQuit&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; doQuit gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; modScore &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: magenta&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                         debug &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Quitter!&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdJet &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;n&lt;span style=&quot;color: red&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; n&amp;#39; &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; parseInt n&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                   Just &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; doJet n&amp;#39;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; cmdJet &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;_&lt;/u&gt;&lt;/span&gt;     &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Nothing&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; doJet n gs &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; n &lt;span style=&quot;color: cyan&quot;&gt;==&lt;/span&gt; location gs&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;               &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                     debug &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;You are already in location &amp;quot;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                              &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; show n &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;               &lt;span style=&quot;color: blue&quot;&gt;-- Jetting increments the turn counter&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;               &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; nextTurn gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                     location &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; n&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                     debug    &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;You have moved to &amp;quot;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                                  &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; show n &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;And we can now test the remaining actions:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; test startState &amp;quot;jet&amp;quot;&lt;br /&gt; Nothing&lt;br /&gt; *Main&amp;gt; test startState &amp;quot;jet 1&amp;quot;&lt;br /&gt; Just (GameState {turn = 2, score = 0, location = 1, &lt;br /&gt;                  debug = &amp;quot;You have moved to 1&amp;quot;})&lt;br /&gt; *Main&amp;gt; test startState &amp;quot;jet 0&amp;quot;&lt;br /&gt; Just (GameState {turn = 1, score = 0, location = 0, &lt;br /&gt;                  debug = &amp;quot;You are already in location 0&amp;quot;})&lt;br /&gt; *Main&amp;gt; test startState &amp;quot;qu&amp;quot;&lt;br /&gt; Just (GameState {turn = 1, score = -10, location = 0, &lt;br /&gt;                  debug = &amp;quot;Quitter!&amp;quot;})&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Next time around, we&amp;#39;ll plug these actions into our prompt, and we&amp;#39;ll work on representing the game state&lt;/p&gt;     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monad-wars---3-command-line-actions.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900e398c18f130001?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monadswars</category>   
        </item> 
 
        <item>
            <title>Monad Wars - 2.5: some comments and corrections</title>
            <link>http://osfameron.vox.com/library/post/monad-wars---25-some-comments-and-corrections.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monad-wars---25-some-comments-and-corrections.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monad-wars---25-some-comments-and-corrections.html?_c=feed-rss-full</guid> 
            <pubDate>Tue, 27 Nov 2007 07:50:45 +0000</pubDate>         
            
            <description>    &lt;p&gt;One of the advantages of demonstrating your ignorance in public is
that you may receive useful corrections... thanks to everyone who
replied on these recent posts, I found the comments very instructive,
and thought it was worth writing up as a new post.&lt;/p&gt;
&lt;h1&gt;Strict records&lt;/h1&gt;

&lt;p&gt;ddarius got in touch to mention that I might want to use “strict fields”.  This might be an issue if I&amp;#39;m incrementing, say, &lt;tt&gt;turn&lt;/tt&gt;,
but not actually using the value. I&amp;#39;d end up building up a “thunk” (an
unevaluated expression) like 1+1+1+1+1+1+1, which will get evaluated
later (and if too much later, it could cause some problems like stack
overflow). Actually, I don&amp;#39;t think this will happen in this particular
case (I&amp;#39;ll be printing the turn count every time) but it&amp;#39;s not hard to
implement (just need to put a “!” before the strict fields)&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;data&lt;/u&gt;&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; GameState &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        turn     &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;!&lt;/span&gt;Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        score    &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        location &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Location&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;deriving&lt;/u&gt;&lt;/span&gt; Show&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Also, as nominolo suggested, in conjunction with &lt;tt&gt;-funbox-strict-fields&lt;/tt&gt;, it can open up some possible optimizations.&lt;/p&gt;
&lt;h1&gt;Not Just Maybe&lt;/h1&gt;

&lt;p&gt;Now this is an interesting one.  I was whining in my last post about &lt;tt&gt;Data.Map.lookup&lt;/tt&gt; &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt; but which monad is it in, and more to the point, why? &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;As you might imagine, I really wasn&amp;#39;t getting it... and the code I wrote around it rather reflects that...&lt;/p&gt;
&lt;p&gt;Vincenz, Rich Neswold, and “rm” all pointed out in rapid succession
that the function I&amp;#39;d created for parseMap was completely redundant.
Here, for comparison, is my first version.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseMap m s &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;member s m &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; v &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;lookup s m&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                                  Just v&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;              &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise    &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;I wrote this because, from the ghci command line, it looked like &lt;tt&gt;M.lookup&lt;/tt&gt; threw an error if it couldn&amp;#39;t find the key. The suggestion, which is rather briefer is as follows:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseMap &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; flip M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;lookup&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;The flip is only there because parseMap and Data.Map.lookup take their arguments in opposite orders.  Otherwise &lt;tt&gt;lookup&lt;/tt&gt; and &lt;tt&gt;parseMap&lt;/tt&gt; are identical!&lt;/p&gt;
&lt;p&gt;But how does this return a “Just” or a “Nothing” appropriately? Apparently, on success, it &lt;tt&gt;return&lt;/tt&gt;s a Monad of the appropriate type by default.  If on the other hand it doesn&amp;#39;t work, it will &lt;tt&gt;fail&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The IO monad maps a fail to an error (which is why I saw the exception I mentioned in the post!)  But Maybe will map it to &lt;tt&gt;Nothing&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So from the &lt;tt&gt;ghci&lt;/tt&gt; command line, we can create a small test Data.Map and run some lookups against it “in” various monads.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; Prelude Data.Map&amp;gt; let m = Data.Map.fromList (&amp;quot;one&amp;quot;, 1)&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; -- success&lt;br /&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;one&amp;quot; m  :: Maybe String&lt;br /&gt; Just &amp;quot;uno&amp;quot;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;one&amp;quot; m  :: [String]&lt;br /&gt; [&amp;quot;uno&amp;quot;]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;one&amp;quot; m  :: IO String&lt;br /&gt; &amp;quot;uno&amp;quot;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; -- fail&lt;br /&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;two&amp;quot; m  :: Maybe String&lt;br /&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;two&amp;quot; m  :: [String]&lt;br /&gt; []&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; Prelude Data.Map&amp;gt; Data.Map.lookup &amp;quot;two&amp;quot; m  :: IO String&lt;br /&gt; *** Exception: user error (Data.Map.lookup: Key not found)&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;ddarius gave a name to this technique, “Not Just Maybe”. That is, if
you were going to write a function that returns Maybe “Just 1“ and
Maybe “Nothing”, then you might as well just write it as a generic
monad. This will then be usable within Maybe, as planned, but also in
IO and List too.&lt;/p&gt;
&lt;p&gt;This sparked an interesting discussion about “Common Idioms” in
Haskell. Apparently the pages that used to exist on this topic haven&amp;#39;t
yet been migrated to the new wiki. But there are some notes, for
example on this snapshot of the &lt;a href=&quot;http://haskell.org/wikisnapshot/NotJustMaybe.html&quot;&gt;NotJustMaybe&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;ddarius also suggested I could rewrite parseInt similarly&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;import&lt;/u&gt;&lt;/span&gt; Control&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;Monad&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; MonadPlus m &lt;span style=&quot;color: red&quot;&gt;=&amp;gt;&lt;/span&gt; String &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; m Int&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt s &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; all isDigit s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; read s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise     &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; mzero&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Using MonadPlus, 1) requires the Control.Monad import. 2) seems to
require the type signature. 3) it looks like IO doesn&amp;#39;t have an mzero,
so you can&amp;#39;t now type&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; parseInt &amp;quot;4&amp;quot; &lt;br /&gt; &amp;lt;interactive&amp;gt;:1:0:&lt;br /&gt;    Ambiguous type variable `m&amp;#39; in the constraint:&lt;br /&gt;      `MonadPlus m&amp;#39;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;at the command line and have it Do The Right Thing. I&amp;#39;d read that &lt;tt&gt;fail&lt;/tt&gt; is considered bad style (for some reason), but it seems to be rather more convenient on these 3 counts at least:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;-- type will be inferred if omitted&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Monad m &lt;span style=&quot;color: red&quot;&gt;=&amp;gt;&lt;/span&gt; String &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; m Int&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt s &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; all isDigit s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; return &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; read s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise     &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; fail &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;not an int&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monad-wars---25-some-comments-and-corrections.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900e398c18ef50001?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monadwars</category>   
        </item> 
 
        <item>
            <title>Monad Wars - 2: the command line</title>
            <link>http://osfameron.vox.com/library/post/monad-wars---2-the-command-line.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monad-wars---2-the-command-line.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monad-wars---2-the-command-line.html?_c=feed-rss-full</guid> 
            <pubDate>Mon, 26 Nov 2007 08:46:32 +0000</pubDate>         
            
            <description>    
&lt;p&gt;This time around, we&amp;#39;re going to look at how we&amp;#39;ll turn user input into commands in Monad Wars.&lt;/p&gt;
&lt;p&gt;I think that the easiest option to implement will also be very
convenient to play with: a command line where we issue commands like:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;    $ buy 4 foo&lt;br /&gt;    $ sell 20  bar&lt;br /&gt;    $ jet bronx&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;or with abbreviations&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;    $ b 4 f&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;and where it&amp;#39;s unambiguous, collapse spaces:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;    $ b4f&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h1&gt;Tokenising&lt;/h1&gt;

&lt;p&gt;We&amp;#39;ll start by tokenising the command line string.  This is &lt;em&gt;almost&lt;/em&gt; as easy as using the Prelude function &lt;tt&gt;words&lt;/tt&gt;.  The only complication is that we want to tokenise alternate letters and numbers separately, like the “b4f” example above.&lt;/p&gt;
&lt;p&gt;We&amp;#39;ll use &lt;tt&gt;groupBy&lt;/tt&gt; from Data.List, and &lt;tt&gt;isLetter&lt;/tt&gt; from Data.Char.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;import&lt;/u&gt;&lt;/span&gt; Data&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;List&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;import&lt;/u&gt;&lt;/span&gt; Data&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;Char&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; tokenizeLine &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;Char&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;Char&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; tokenizeLine &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; concatMap &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                   &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;groupBy &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;`on`&lt;/span&gt; isLetter&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                   &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; words&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Annoyingly, &lt;tt&gt;on&lt;/tt&gt; (in the Prelude in GHC 6.8) doesn&amp;#39;t exist in my 6.6.1 installation, so we&amp;#39;ll have to define it:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; op &lt;span style=&quot;color: cyan&quot;&gt;`on`&lt;/span&gt; p &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;\&lt;/span&gt;a b &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; p a &lt;span style=&quot;color: cyan&quot;&gt;`op`&lt;/span&gt; p b&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Let&amp;#39;s just see how groupBy works:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; groupBy (==) &amp;quot;aabbbcdd&amp;quot;&lt;br /&gt; [&amp;quot;aa&amp;quot;,&amp;quot;bbb&amp;quot;,&amp;quot;c&amp;quot;,&amp;quot;dd&amp;quot;]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; groupBy (\a b -&amp;gt; isLetter a == isLetter b) &amp;quot;abc123def&amp;quot;&lt;br /&gt; [&amp;quot;abc&amp;quot;,&amp;quot;123&amp;quot;,&amp;quot;def&amp;quot;]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;The &lt;tt&gt;on&lt;/tt&gt; expression is a nicer way of writing the second
case. We then map this grouping over each of the tokens, getting our
final list.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; tokenizeLine &amp;quot;jet quuxville&amp;quot;&lt;br /&gt; [&amp;quot;jet&amp;quot;,&amp;quot;quuxville&amp;quot;]&lt;br /&gt; *Main&amp;gt; tokenizeLine &amp;quot;b3p&amp;quot;&lt;br /&gt; [&amp;quot;b&amp;quot;,&amp;quot;3&amp;quot;,&amp;quot;p&amp;quot;]&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h1&gt;Parsing&lt;/h1&gt;

&lt;p&gt;Now we&amp;#39;ll want to do things with the tokens. Yes, there are
libraries to do this (Parsec etc.) I know that in the Perl world I&amp;#39;d
often tell other people not to reinvent the wheel and to use CPAN, so I
do feel a little naughty that I&amp;#39;m going to ignore these and handroll
something myself. In my defence m&amp;#39;ludd,&lt;/p&gt;
&lt;ul&gt;&lt;li&gt; I&amp;#39;m only parsing very simple commands &lt;/li&gt;&lt;li&gt;
Learning a new library requires cognitive effort. I have limited time
for this task, and I believe (possibly wrongly) that I will be able to
“roll my own” more quickly. &lt;/li&gt;&lt;li&gt; Reimplementing functionality can be instructive in and of itself &lt;/li&gt;&lt;li&gt; It also makes you appreciate how simple the “official” solution really is, when you finally get around to learning it. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;In an expression like &lt;tt&gt;buy 4 foo&lt;/tt&gt; I&amp;#39;m imagining that “buy”
will map to some command. Then we&amp;#39;ll need to parse “4“ as a number, and
“foo” as a some merchandise. The first case is the simplest:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; String &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; Maybe Int&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseInt s &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; all isDigit s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Just &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; read s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise     &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;This reads tantalisingly close to English: If all the string is made
up of digits, we just read it as an Integer. Otherwise we return
nothing. OK, I&amp;#39;m glossing rather over the “Just” and “Nothing” which
indicate whether the parse succeeded using the “Maybe” monad.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; parseInt &amp;quot;42&amp;quot;&lt;br /&gt; Just 42&lt;br /&gt; *Main&amp;gt; parseInt &amp;quot;wibble&amp;quot;&lt;br /&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Now for parsing the merchandise: if there is an item called “foo”,
we&amp;#39;d want to match “foo”, “fo”, “f”. By amazing coincidence, I recently
&lt;a href=&quot;http://osfameron.vox.com/library/post/haskell-snippet---getprefixmap.html&quot;&gt; wrote about a function&lt;/a&gt; that does exactly what we need:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;import&lt;/u&gt;&lt;/span&gt; qualified Data&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;Map &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;as&lt;/u&gt;&lt;/span&gt; M&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;import&lt;/u&gt;&lt;/span&gt; Control&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;Arrow&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; getPrefixes &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;a&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; t&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;a&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; t&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; getPrefixes &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; concatMap &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; uncurry zip &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;tail &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; inits &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; fst &lt;span style=&quot;color: cyan&quot;&gt;&amp;amp;&amp;amp;&amp;amp;&lt;/span&gt; repeat &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; snd&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; getPrefixMap &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;Ord a&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;a&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; t&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;Map &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;a&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt; t&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; getPrefixMap &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;fromList &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; getPrefixes&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;So we&amp;#39;d need a list of merchandise. Which means we should think a
little about what the datatype will look like. I&amp;#39;m going with a record
type again, because I know there is more information that we&amp;#39;ll need to
store:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;data&lt;/u&gt;&lt;/span&gt; Merchandise &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Merchandise &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  name &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; String&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  min  &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Int&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;    &lt;span style=&quot;color: blue&quot;&gt;-- minimum price&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  max  &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Int     &lt;span style=&quot;color: blue&quot;&gt;-- maximum price&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;deriving&lt;/u&gt;&lt;/span&gt; Show&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Next, we define the products on offer, by looking at the Dope Wars
configuration pages, we can copy the prices, but of course we have to
theme the names...&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; merchandise &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;Merchandise&lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; merchandise &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;[&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Arrows&amp;quot;&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;1000&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;4400&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Curry&amp;quot;&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;15000&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;29000&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Kleisli&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;480&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;1280&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Haskell&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;5500&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;13000&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Lambdas&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;11&lt;/span&gt;    &lt;span style=&quot;color: magenta&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;STM&amp;quot;&lt;/span&gt;     &lt;span style=&quot;color: magenta&quot;&gt;1500&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;4400&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Monads&amp;quot;&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;540&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;1250&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;GHC&amp;quot;&lt;/span&gt;     &lt;span style=&quot;color: magenta&quot;&gt;1000&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;2500&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Peyton&amp;quot;&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;220&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;700&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Fundeps&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;630&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;1300&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Zipper&amp;quot;&lt;/span&gt;  &lt;span style=&quot;color: magenta&quot;&gt;90&lt;/span&gt;    &lt;span style=&quot;color: magenta&quot;&gt;250&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    Merchandise &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Endo&amp;quot;&lt;/span&gt;    &lt;span style=&quot;color: magenta&quot;&gt;315&lt;/span&gt;   &lt;span style=&quot;color: magenta&quot;&gt;890&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span style=&quot;color: red&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Now this isn&amp;#39;t in the form we need it yet.  First of all, we&amp;#39;ll map this list to a list of tuples of &lt;tt&gt;[(string, thing),...]&lt;/tt&gt;, which is exactly what getPrefixMap is expecting:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; merchandiseMap &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; getPrefixMap &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  map &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;\&lt;/span&gt;i &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;toLowerS &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; name i&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt; i&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  merchandise&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;-- toLowerS over a string isn&amp;#39;t defined by default, but it&amp;#39;s just:&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; toLowerS &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; map toLower&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;OK, for a bit of fun, we could write the &lt;tt&gt;map&lt;/tt&gt; as:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;              &lt;span style=&quot;color: blue&quot;&gt;-- map (toLowerS . name &amp;amp;&amp;amp;&amp;amp; id)&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;(I don&amp;#39;t yet understand why “arrows” are supposed to be an “even
more generic model of computation than monads”, but they&amp;#39;re certainly
good for putting things in tuples :-)&lt;/p&gt;
&lt;p&gt;Now we can build the parser parseMerchandise. Or rather (as we&amp;#39;ll
probably use this technique again, for example for the names of
locations, and even the commands like “buy” and “jet”), we&amp;#39;ll create &lt;tt&gt;parseMap&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Interestingly Data.Map&amp;#39;s &lt;tt&gt;lookup&lt;/tt&gt; function throws an
exception (as a “user error”!) if you try to look up a key that doesn&amp;#39;t
exist. (This is rather different from Perl hashes, but it makes sense
in a strongly typed language - there is no “undef” value which is of
the requested type!) So that I can avoid having to learn exceptions
just yet, I&amp;#39;m going to check first of all if the key exists using &lt;tt&gt;member&lt;/tt&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseMap m s &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;member s m &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; v &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; M&lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt;lookup s m&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                                  Just v&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;              &lt;span style=&quot;color: red&quot;&gt;|&lt;/span&gt; otherwise    &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;I spent about half an hour trying to get the above to work. After a
number of rather unhelpful error messages about monads, I changed from
my original attempt &lt;tt&gt;v = M.lookup s m&lt;/tt&gt; to the do-notation form. This is rather odd, as it implies that &lt;tt&gt;lookup&lt;/tt&gt; is monadic. And its type does indeed suggest that the result is in &lt;em&gt;some&lt;/em&gt; monad...&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; :t M.lookup&lt;br /&gt; M.lookup :: (Ord k, Monad m) =&amp;gt; k -&amp;gt; M.Map k a -&amp;gt; m a&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;but which monad is it in, and more to the point, &lt;em&gt;why&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;In any case, now it&amp;#39;s easy as pie(*) to create our merchandise parser as a specialization of our general function:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseMerchandise &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; String &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; Maybe Merchandise&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseMerchandise &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; parseMap merchandiseMap&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;and we can now recognize the names and abbreviations of elements in the list!&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; parseMerchandise &amp;quot;pey&amp;quot;&lt;br /&gt; Just (Merchandise {name = &amp;quot;Peyton&amp;quot;, min = 220, max = 700})&lt;br /&gt; *Main&amp;gt; parseMerchandise &amp;quot;vb&amp;quot;&lt;br /&gt; Nothing&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Next time around, we&amp;#39;ll create “buy” and “sell” handlers that parse
the whole command line, and stub in the actual interaction with the
game state!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;(*) Well, I say easy, but at this point (and ongoing) we get bitten
by the “monomorphism restriction”, whatever that is. The error message
suggests that you add explicit types to all the functions involved, but
when I try that, I regularly get even stranger error messages about
rigid variables and monads. The easier solution seems to be to add &lt;tt&gt;-fno-monomorphism-restriction&lt;/tt&gt;
to your ghci call. (I don&amp;#39;t know enough to know whether this is a Bad
Thing). Of course, now this error message doesn&amp;#39;t come up. Pah!&lt;/p&gt;
     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monad-wars---2-the-command-line.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900e398c138300001?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monadwars</category>   
        </item> 
 
        <item>
            <title>Monad Wars - 1: the Prompt</title>
            <link>http://osfameron.vox.com/library/post/monad-wars---1-the-prompt.html?_c=feed-rss-full</link>   
            <author>nobody@vox.com(osfameron)</author>
            <comments>http://osfameron.vox.com/library/post/monad-wars---1-the-prompt.html?_c=feed-rss-full</comments>
            <guid isPermaLink="true">http://osfameron.vox.com/library/post/monad-wars---1-the-prompt.html?_c=feed-rss-full</guid> 
            <pubDate>Fri, 23 Nov 2007 13:22:27 +0000</pubDate>         
            
            <description>    &lt;p&gt;A lot of learning projects involve writing games: people have
written clones of Tetris, Asteroids, Space Invaders, and even first
person shooters (Frag) in Haskell. As I&amp;#39;m far less clever than these
people, I thought I&amp;#39;d start with something a bit simpler: &lt;a href=&quot;http://dopewars.sourceforge.net/screenshots/&quot;&gt;Dope Wars&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dope Wars is basically a trading game. In 30 turns, you move from
one location to another, buying and selling, er, drugs on the streets
of New York. It&amp;#39;s a fairly simple concept, but one which includes
elements like:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Input and Output     &lt;/li&gt;&lt;li&gt;Game state     &lt;/li&gt;&lt;li&gt;Random numbers &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;all of which seem like a good way to learn Monads and the other
building blocks that you need to actually do anything useful in a
functional programming language like Haskell.&lt;/p&gt;
&lt;p&gt;So I had the idea, wrote up a couple of datatypes and some
functions, and then forgot about it. Then, when Greg McCarroll
mentioned that he&amp;#39;d accept talks about other languages for the &lt;a href=&quot;http://conferences.yapceurope.org/lpw2007/&quot;&gt;London Perl Workshop&lt;/a&gt; on December 1st, I thought it would be a great opportunity to push myself to do it by proposing a &lt;a href=&quot;http://conferences.yapceurope.org/lpw2007/talk/843&quot;&gt; lightning talk&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Only problem: I now have to actually write the game in order to talk
about it (*). So... here goes. In this post, I&amp;#39;m going to show a first
draft for the game prompt.&lt;/p&gt;
&lt;h1&gt;State&lt;/h1&gt;

&lt;p&gt;OK, people often find it most convenient to do State using “Monads”.
I think I&amp;#39;m going to leave that for now, and just thread state
explicitly. Mainly because I haven&amp;#39;t yet got around to learning how to
use the State Monad. Hopefully this will eventually become annoying
enough that it will give me impetus to learn the monadic version.&lt;/p&gt;
&lt;p&gt;Anyway, the idea here is that we&amp;#39;d have some function playTurn that will look a bit like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; playTurn &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; IO &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; playTurn gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;let&lt;/u&gt;&lt;/span&gt; gs&amp;#39; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; doSomething gs&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;               &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;in&lt;/u&gt;&lt;/span&gt;  playTurn gs&amp;#39;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;(There is an interesting &lt;a href=&quot;http://www.nabble.com/An-interesting-monad:-%22Prompt%22-p13825883.html&quot;&gt; post&lt;/a&gt; on haskell-cafe about a more sophisticated monadic representation of the prompt).&lt;/p&gt;
&lt;p&gt;So we just need to work out how to represent this GameState object. To start off with, we&amp;#39;ll want to store information like&lt;/p&gt;
&lt;ul&gt;&lt;li&gt; Which turn it is &lt;/li&gt;&lt;li&gt; What our score is (how much money we have) &lt;/li&gt;&lt;li&gt; Where we are on the game map &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We could create a normal tuple:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;data&lt;/u&gt;&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; GameState Integer Integer Location&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                         &lt;span style=&quot;color: blue&quot;&gt;-- turn    score   location&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;and then pattern match on this, but it&amp;#39;s going to get horrible if we
add any fields later on! In Perl I&amp;#39;d just use a hash, but remember that
Haskell Data.Map objects map from one type to another, and we might
well have values of various types.&lt;/p&gt;
&lt;p&gt;When I asked on #haskell, dons and firefly told me about the record syntax:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;data&lt;/u&gt;&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; GameState &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        turn     &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        score    &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;        location &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Location&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;deriving&lt;/u&gt;&lt;/span&gt; Show&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;-- for now:&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;type&lt;/u&gt;&lt;/span&gt; Location &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; Integer&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Defining the original state is easy:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; startState &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; GameState &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    turn     &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    score    &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; 0&lt;span style=&quot;color: cyan&quot;&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;    location &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; 0&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;  &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;And to “modify” it (or rather to clone it, overriding certain
fields) there is a convenient syntax that just lets us declare those
fields which have changed:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; movedToBronx &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; location &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; bronx &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Setting a field to a value is easy, but we might want to define some mutators to change the field relative to its current value:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; nextTurn &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; GameState&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; nextTurn gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; turn &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; succ &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; turn gs &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; modScore &lt;span style=&quot;color: red&quot;&gt;::&lt;/span&gt; Integer &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; GameState &lt;span style=&quot;color: red&quot;&gt;-&amp;gt;&lt;/span&gt; GameState&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; modScore d gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; gs &lt;span style=&quot;color: cyan&quot;&gt;{&lt;/span&gt; score &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; score gs &lt;span style=&quot;color: cyan&quot;&gt;+&lt;/span&gt; d &lt;span style=&quot;color: cyan&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;The record syntax will work even when we inevitably add new fields later.  Yay!&lt;/p&gt;
&lt;h1&gt;Prompt&lt;/h1&gt;

&lt;p&gt;Now, the game cycle is a bit more complicated than the version I
suggested above, as it will allow IO actions in it. Something perhaps
like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; playTurn gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; showStatus gs&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  putStr prompt&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  s &lt;span style=&quot;color: red&quot;&gt;&amp;lt;-&lt;/span&gt; getLine&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;let&lt;/u&gt;&lt;/span&gt; f &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; parseLine s&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;let&lt;/u&gt;&lt;/span&gt; gs&amp;#39; &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; f gs&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                  &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;if&lt;/u&gt;&lt;/span&gt; isEnd gs&amp;#39; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                     &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;then&lt;/u&gt;&lt;/span&gt; endGame  gs&amp;#39;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                     &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;else&lt;/u&gt;&lt;/span&gt; playTurn gs&amp;#39;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;For now we&amp;#39;ll just stub some of the declarations we need. &lt;tt&gt;showStatus&lt;/tt&gt; can just &lt;tt&gt;show&lt;/tt&gt; the GameState record (which is why we derived the Show class).&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; showStatus gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; putStrLn &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; show gs&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;We may as well set the prompt to the dollar sign, appropriately:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; prompt   &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;$ &amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Though we&amp;#39;ll need to parse the line read from standard input to one
of the commands like “Buy 4 X” or “Goto location 3“, right now, we&amp;#39;ll
just stub in a function that increments the score and the turn counter:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; parseLine s &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt;   nextTurn &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;               &lt;span style=&quot;color: cyan&quot;&gt;.&lt;/span&gt; modScore &lt;span style=&quot;color: magenta&quot;&gt;10&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;We need to know if we&amp;#39;re at the end of the game, and take action appropriately.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; isEnd gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; turn gs &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; maxTurns&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; maxTurns &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;3&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt; endGame gs &lt;span style=&quot;color: red&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green&quot;&gt;&lt;u&gt;do&lt;/u&gt;&lt;/span&gt; putStrLn   &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Game over!&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                 putStrLn &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; &lt;span style=&quot;color: magenta&quot;&gt;&amp;quot;Your score was &amp;quot;&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;show &lt;span style=&quot;color: cyan&quot;&gt;$&lt;/span&gt; score gs&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: cyan&quot;&gt;&amp;gt;&lt;/span&gt;                 return &lt;span style=&quot;color: cyan&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: cyan&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;And here&amp;#39;s a transcript&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt; *Main&amp;gt; playTurn startState&lt;br /&gt; GameState {turn = 1, score = 10, location = 0}&lt;br /&gt; &amp;gt; buy  2 foo&lt;br /&gt; GameState {turn = 2, score = 20, location = 0}&lt;br /&gt; &amp;gt; sell 4 bar&lt;br /&gt; GameState {turn = 3, score = 30, location = 0}&lt;br /&gt; &amp;gt; goto quuxtown&lt;br /&gt; Game over!&lt;br /&gt; Your score was 40&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;(*) to be fair, it&amp;#39;s only a 5 minute “Lightning Talk”, so I could
probably get away without even writing the whole game, but I&amp;#39;ll feel
better if I actually know what I&amp;#39;m talking about...&lt;/p&gt;
     &lt;p style=&quot;clear:both;&quot;&gt;

    &lt;a href=&quot;http://osfameron.vox.com/library/post/monad-wars---1-the-prompt.html?_c=feed-rss-full#comments&quot;&gt;Read and post comments&lt;/a&gt;

 | 

    
    &lt;a href=&quot;http://www.vox.com/share/6a00c225240a9af21900e398c069580005?_c=feed-rss-full&quot;&gt;Send to a friend&lt;/a&gt;

&lt;/p&gt;
 
            </description> 
            <category domain="http://osfameron.vox.com/tags/">haskell</category> 
            <category domain="http://osfameron.vox.com/tags/">monadwars</category>   
        </item> 
    </channel>
</rss>

