<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Random Hacks: Monads in 15 minutes: Backtracking and Maybe</title>
    <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Technology and Other Fun Stuff</description>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Doug Auclair</title>
      <description>&lt;p&gt;Linking this article on an introductory post about Maybe, List and Either monads and their uses for nondeterministic programming.&lt;/p&gt;


	&lt;p&gt;Coincidentally, I wrote a same-game-like puzzle solver (cf. comp.lang.haskell), where I needed to flatten a list of lists.  I didn&amp;#8217;t see `flatten` in the Prelude or List, so I wrote it out.  I then realized that `msum` is flatten for lists of depth 1 &amp;#8230; then I reread this article where join :: m (m a) &amp;rarr; m a does the same thing.  Applied that in my code and noticed I had this pattern: join $ map f x &amp;#8230; and replaced that with x &gt;&gt;= f.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Sigh&lt;/strong&gt;! Months later and I&amp;#8217;m still not recognizing when to use a simple bind!&lt;/p&gt;</description>
      <pubDate>Wed, 14 May 2008 01:39:52 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:45f28eaf-7838-4a02-a8b8-14f35a921082</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-571</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Joel Hough</title>
      <description>&lt;p&gt;Great article!  A few things clicked for me while reading.  I found that writing out the choice monad example step by step helped me to understand.  Like so:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-definition'&gt;choose&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;1&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;2&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;3&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt; &lt;span class='hs-varop'&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;\&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt;
&lt;span class='hs-definition'&gt;choose&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;4&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;5&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;6&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt; &lt;span class='hs-varop'&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;\&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt;
&lt;span class='hs-definition'&gt;guard&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-varop'&gt;*&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-varop'&gt;==&lt;/span&gt;&lt;span class='hs-num'&gt;8&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-varop'&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;\&lt;/span&gt;&lt;span class='hs-varid'&gt;ignored&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt;
&lt;span class='hs-definition'&gt;return&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
is equivalent to&amp;#8230;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-definition'&gt;step1&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-varid'&gt;concat&lt;/span&gt; &lt;span class='hs-varop'&gt;$&lt;/span&gt; &lt;span class='hs-varid'&gt;map&lt;/span&gt; &lt;span class='hs-varid'&gt;step2&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;1&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;2&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;3&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;span class='hs-definition'&gt;step2&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-varid'&gt;concat&lt;/span&gt; &lt;span class='hs-varop'&gt;$&lt;/span&gt; &lt;span class='hs-varid'&gt;map&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;step3&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;4&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;5&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;6&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;span class='hs-definition'&gt;step3&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-varid'&gt;concat&lt;/span&gt; &lt;span class='hs-varop'&gt;$&lt;/span&gt; &lt;span class='hs-varid'&gt;map&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;step4&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-keyword'&gt;if&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-varop'&gt;*&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-varop'&gt;==&lt;/span&gt; &lt;span class='hs-num'&gt;8&lt;/span&gt; &lt;span class='hs-keyword'&gt;then&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt; &lt;span class='hs-keyword'&gt;else&lt;/span&gt; &lt;span class='hs-conid'&gt;[]&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
&lt;span class='hs-definition'&gt;step4&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-keyword'&gt;_&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt; &lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Thanks for the epiphanies!&lt;/p&gt;</description>
      <pubDate>Thu, 10 Apr 2008 03:29:26 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:df7d3e3c-c8bf-4469-94c1-b44ff7f1fca5</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-570</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;David: Excellent questions! The &amp;#8220;map&amp;#8221; function used in monads is a generalization of the regular &amp;#8220;map&amp;#8221;.&lt;/p&gt;


This will make more sense if you think of &amp;#8220;Maybe&amp;#8221; as a very specialized container&lt;hr /&gt;a container which can only hold a single element.  From that perspective, &amp;#8220;mapMaybe&amp;#8221; looks very natural:


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-definition'&gt;mapMaybe&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;::&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;a&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='hs-varid'&gt;b&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='hs-conid'&gt;Maybe&lt;/span&gt; &lt;span class='hs-varid'&gt;a&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='hs-conid'&gt;Maybe&lt;/span&gt; &lt;span class='hs-varid'&gt;b&lt;/span&gt;
&lt;span class='hs-definition'&gt;mapMaybe&lt;/span&gt; &lt;span class='hs-varid'&gt;f&lt;/span&gt; &lt;span class='hs-conid'&gt;Nothing&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-conid'&gt;Nothing&lt;/span&gt;
&lt;span class='hs-definition'&gt;mapMaybe&lt;/span&gt; &lt;span class='hs-varid'&gt;f&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-conid'&gt;Just&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-conid'&gt;Just&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;f&lt;/span&gt; &lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;In English, this says: &amp;#8220;If the container is empty, leave it that way. If it contains an element, apply &amp;#8216;f&amp;#8217; to the element.&amp;#8221; Basically, it&amp;#8217;s no different than applying &amp;#8220;map&amp;#8221; to a zero- or one-element list.&lt;/p&gt;


	&lt;p&gt;As for the IO monad, don&amp;#8217;t worry too much about it. :-) It&amp;#8217;s actually a pretty atypical monad.&lt;/p&gt;


	&lt;p&gt;But if it helps, try reading the type &amp;#8220;IO a&amp;#8221; as &amp;#8220;an IO action returning type a&amp;#8221;. Again, if you squint at it right, you can think of an IO action as a single-element collection. You just have to some IO to find out what element is stored in it!&lt;/p&gt;


	&lt;p&gt;The &amp;#8220;mapIO&amp;#8221; function can be defined as:&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;Perform the IO action and extract the value of type &amp;#8220;a&amp;#8221;.&lt;/li&gt;
&lt;li&gt;Calculate &amp;#8220;f a&amp;#8221;, and jam the result back into a dummy IO action.&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Does this help any?&lt;/p&gt;</description>
      <pubDate>Mon, 28 Jan 2008 15:58:56 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:27f45c42-54fe-462c-8967-1f68b22a4385</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-550</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by David</title>
      <description>&lt;p&gt;Thanks for this! I&amp;#8217;ve read a lot about Haskell but I&amp;#8217;ve been confounded by monads. I&amp;#8217;ve read every tutorial I&amp;#8217;ve found and each helps me understand a little bit more. This one was very helpful. I have an unanswered question though&amp;#8230;&lt;/p&gt;


	&lt;p&gt;The map part of a monad doesn&amp;#8217;t seem to have to be the actual &amp;#8220;map&amp;#8221; function. The Maybe monad&amp;#8217;s &amp;#8220;map&amp;#8221; seems to just propagate the Nothing or Just along as appropriate. Is this correct?&lt;/p&gt;


	&lt;p&gt;How does this work in the case of the IO monad? I&amp;#8217;ve been staring at the &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-IOBase.html#IO"&gt;&lt;span class="caps"&gt;GHC&lt;/span&gt; prelude code&lt;/a&gt; for the past 15 minutes but I&amp;#8217;m not fully comprehending what it is doing. I &lt;em&gt;think&lt;/em&gt; its &gt;&gt;= function is just doing a function application instead of a &amp;#8220;map&amp;#8221;, but I&amp;#8217;m not sure (that case part is confusing me). I &lt;em&gt;do&lt;/em&gt; see the &amp;#8220;join&amp;#8221; where it strips out nested IOs. Can anyone help out?&lt;/p&gt;</description>
      <pubDate>Sun, 27 Jan 2008 13:29:03 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:1869586d-9739-4ee9-9593-0b37c73fcf78</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-549</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Michael</title>
      <description>&lt;p&gt;To add to what Eric wrote, I&amp;#8217;d go so far as to say that monads aren&amp;#8217;t even all that mysterious, but in fact you will have an easier time understanding them (at least in terms of their utility to a programmer) if you just forget about category theory entirely.&lt;/p&gt;


From a programmer&amp;#8217;s perspective, a monad is more or less a way of factoring out some common code from various types of operations that are composed sequentially.  The fact that this is possible seems strange at first&lt;hr /&gt;and I think that&amp;#8217;s what leads people to feel monadic types are confusing.  Well, that, and the terminology, which can be misleadingly abstruse.</description>
      <pubDate>Thu, 29 Nov 2007 17:54:39 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:985a2149-716d-455e-9d59-4aa57dc82af5</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-540</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;Monads are a somewhat mysterious programming language feature, most commonly encountered in Haskell. See the examples I link to in the first paragraph.&lt;/p&gt;


	&lt;p&gt;Basically, monads are a clever bit of category theory that can be used to structure control flow in a program.&lt;/p&gt;


	&lt;p&gt;If you weren&amp;#8217;t already thinking, &amp;#8220;Hmm, I really ought to learn more about monads,&amp;#8221; then you might be happier avoiding the entire topic. :-)&lt;/p&gt;</description>
      <pubDate>Thu, 29 Nov 2007 14:50:33 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b6ee40f9-c05c-4fd4-91a1-ac9312b37c08</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-539</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Dan Dingleberry</title>
      <description>&lt;p&gt;Dude, &lt;span class="caps"&gt;WTH&lt;/span&gt; is a monad? at least define the dang thing first for casual passers by.&lt;/p&gt;</description>
      <pubDate>Wed, 28 Nov 2007 19:58:06 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:090d2481-2f4b-4031-a2f7-60b9b6136ebe</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-538</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Doug Auclair</title>
      <description>&lt;p&gt;Of course, it&amp;#8217;s been pointed out in other papers about monads that the do notation:&lt;/p&gt;


	&lt;p&gt;do x &lt;- choose [1,2,3]
...&lt;/p&gt;


	&lt;p&gt;is very similar to the list compression notation: [x|x &lt;- [1,2,3]]&lt;/p&gt;


	&lt;p&gt;(in fact, gopher, Haskell&amp;#8217;s predecessor, they were so similar that they were the same thing)&lt;/p&gt;


	&lt;p&gt;And, seeing that the type Choice is an alias for the list type, the monadic expression can simply be rewritten: [(x,y)|x&lt;&lt;del&gt; [1,2,3], y&lt;&lt;/del&gt;[4,5,6], x*y == 8]&lt;/p&gt;


	&lt;p&gt;Haskell programmers claim their list compression is even more powerful that Prolog&amp;#8217;s, and the above example is good supporting evidence &amp;#8230;&lt;/p&gt;</description>
      <pubDate>Thu, 15 Nov 2007 15:00:21 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:338003b2-b873-4a20-a63e-578685a488e2</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-535</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Doug Auclair</title>
      <description>&lt;p&gt;Finally!  (an aside: I did read the LogicT paper)  I&amp;#8217;ve been looking for concise backtracking in Haskell.  Of course, it&amp;#8217;s been there all the time, and there&amp;#8217;s been several mentions that monads permit backtracking, but your tutorial, Eric, gave me a simple and clear example.  Thank you.  I&amp;#8217;ll start working through some other (similar) examples.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve also read Reasoned Schemer (Dr. William Byrd autographed it for me at the &lt;span class="caps"&gt;PADL 2006&lt;/span&gt;) several times, so I&amp;#8217;m looking to combine that and LogicT and your example into a full-blown (concise) rule- or relational-based programming system.  Backtracking is key, but do I need full unification?  Not too sure.&lt;/p&gt;


	&lt;p&gt;Thanks, again.&lt;/p&gt;</description>
      <pubDate>Wed, 14 Nov 2007 17:39:32 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b5356488-af5c-40df-9b63-2dc711e04887</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-533</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Sampo</title>
      <description>&lt;p&gt;Now that was helpful. Time well spend even though it was a bit more than 15 minutes :-) I think you managed to bring me on the verge of understanding monads.&lt;/p&gt;


	&lt;p&gt;I think the Option -monad explanation did it for me&amp;#8230; I&amp;#8217;m reiterating just to see if I really understand:
I see the the functions returnMaybe, mapMaybe and joinMaybe as &amp;#8216;rules&amp;#8217;. For example mapMaybe tells how to handle function calls where arguments belong to Maybe -monad.
1) If function gets called with Nothing, the return value will always be Nothing. 
2) If function gets called with a valid value Just(x), the value x is extracted from Just(x) and handed to the function.&lt;/p&gt;


	&lt;p&gt;This ensures the Maybe works as expected but not every function needs to know how to handle them.&lt;/p&gt;


	&lt;p&gt;joinMaybe defines how to handle the returned (nested) values. If the nested values all are Just(something) we can get rid of extra Justs and keep values. If there is a single Nothing, everything will end up being Nothing.&lt;/p&gt;</description>
      <pubDate>Sat, 20 Oct 2007 18:01:39 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:21301456-8a97-49ee-af74-21f843d162b3</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-522</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Drew Vogel</title>
      <description>&lt;p&gt;I understand the Haskell constructs involved in your example, but I had trouble finding the actual backtracking. I learned of backtracking as an optimization of a search algorithm that worked by tossing out large chunks of the search space. Because 2*4 is the only combination that equals 8, it isn&amp;#8217;t obvious that the &amp;#8220;take 1&amp;#8221; is throwing out the rest of the problem space. Perhaps you could use a combination of the even function and infinite lists to increase the search space and illustrate how you are tossing out a portion of the search space.&lt;/p&gt;


	&lt;p&gt;Also, a single file with the final code would be wonderful. It&amp;#8217;s hard looking at it outside of vim :)&lt;/p&gt;</description>
      <pubDate>Fri, 19 Oct 2007 14:08:52 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f1b822b2-b9db-4e1b-9877-2a24555b92ab</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-521</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Michael</title>
      <description>&lt;p&gt;Nice tutorial, maybe would be a good idea to abstract to tuples of arbitrary length instead of just pairs, to make the backtracking even more obvious.&lt;/p&gt;</description>
      <pubDate>Mon, 13 Aug 2007 08:51:11 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:de7f29ba-15fc-495f-befc-d294559fe882</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-487</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Erik</title>
      <description>&lt;p&gt;Eric:  Yes, after making that post I went on to read the &amp;#8220;All About Monads&amp;#8221; link you placed at the end of the post and came to that understanding.  Thanks!&lt;/p&gt;</description>
      <pubDate>Mon, 30 Jul 2007 11:07:40 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0bbeb3d7-fe5e-4083-95da-457d5f85b10f</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-485</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;Erik: Well, a list comprehension &lt;i&gt;is&lt;/i&gt; a monad. Or, if you want to look at it the other way around, a monad is a generalized comprehension that can be defined for almost any parameterized data type.&lt;/p&gt;


	&lt;p&gt;For a more complicated monad, see &lt;a href="http://www.randomhacks.net/articles/2007/02/22/bayes-rule-and-drug-tests"&gt;Bayes&amp;#8217; rule in Haskell&lt;/a&gt;. For a rather different monad, see &lt;a href="http://research.microsoft.com/~simonpj/papers/stm/index.htm"&gt;&lt;span class="caps"&gt;SPJ&lt;/span&gt;&amp;#8217;s papers on Software Transactional Memory&lt;/a&gt;. Basically, by slightly generalizing list comprehensions, you get a tool which solves a surprisingly large and diverse set of problems.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll write a longer post one of these days cataloging a bunch of useful monads. Until then, would anyone like to plug their favorite monads? :-)&lt;/p&gt;</description>
      <pubDate>Sun, 29 Jul 2007 18:57:33 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:8dad76b9-003d-43e3-a86c-aeb9cb8028d0</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-484</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Erik</title>
      <description>&lt;p&gt;So, before going back over this posting using a full fifteen minutes (I just skimmed it), why use an example that could be solved with the following?&lt;/p&gt;


	&lt;p&gt;fun :: [Int] &amp;rarr; [Int] &amp;rarr; [(Int, Int)]
fun r s = [(x,y) | x &lt;&lt;del&gt; r, y &lt;&lt;/del&gt; s, x*y == 8]&lt;/p&gt;


	&lt;p&gt;I find that when toy problems with both simple and obvious solutions are used to demonstrate hard concepts it can obfuscate the idea because while you may be showing the how of the concept, you aren&amp;#8217;t explaining the why.&lt;/p&gt;


	&lt;p&gt;Could you maybe show an example of join that wouldn&amp;#8217;t be simple to express with a simple list comprehension?&lt;/p&gt;</description>
      <pubDate>Sun, 29 Jul 2007 18:29:47 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:ee5cd41b-74d3-4b09-9903-b636e22db6e0</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-483</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;Steven: Don&amp;#8217;t assume that the simplest  example of something is also the most compelling. :-)&lt;/p&gt;


	&lt;p&gt;For more interesting monads, see the &lt;a href="http://research.microsoft.com/~simonpj/papers/stm/"&gt; the paper on composable memory transactions&lt;/a&gt;, the various &lt;a href="http://www.randomhacks.net/tag/Probability"&gt;probability monads&lt;/a&gt;, sigfpe&amp;#8217;s article on &lt;a href="http://sigfpe.blogspot.com/2007/06/how-to-write-tolerably-efficient.html"&gt;graph-walking monads&lt;/a&gt;, and the paper on using &lt;a href="http://web.cecs.pdx.edu/%7Eapt/icfp05.pdf"&gt;monads for safe hardware abstraction&lt;/a&gt; (PDF). If you work with .NET, you may also want to check out Microsoft&amp;#8217;s new &lt;a href="http://lambda-the-ultimate.org/node/967"&gt;&lt;span class="caps"&gt;LINQ&lt;/span&gt;&lt;/a&gt; technology, which relies heavily on monads for database access and &lt;span class="caps"&gt;XML&lt;/span&gt; processing.&lt;/p&gt;


	&lt;p&gt;Once you understand monads, you start seeing them everywhere&amp;#8212;they&amp;#8217;re very general tools, and they can be used to solve a wide variety of problems.&lt;/p&gt;


	&lt;p&gt;As with any other abstraction, you can do without monads. But if one abstraction solves so many problems so elegantly, it&amp;#8217;s worth learning about.&lt;/p&gt;</description>
      <pubDate>Fri, 29 Jun 2007 07:57:07 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:d47143ca-09dc-4b49-8f9a-f4eeecd4e643</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-471</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Steven Brandt</title>
      <description>&lt;p&gt;As an old imperative programmer I can&amp;#8217;t help but think this is just like:&lt;/p&gt;


	&lt;p&gt;for(int x=1;x&lt;=3;x++) {
  for(int y=4;y&lt;=6;y++) {
    if(x*y == 8) {
      list.append(new Pair(x,y));
    }
  }
}&lt;/p&gt;


	&lt;p&gt;Except the imperative code is a lot easier to understand. I&amp;#8217;m trying really hard to understand monads and see their value, but I still can&amp;#8217;t quite get there.&lt;/p&gt;</description>
      <pubDate>Wed, 27 Jun 2007 10:36:15 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:7c64f566-775d-442d-b3ad-323639f5bc6d</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-470</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by osfameron</title>
      <description>&lt;p&gt;Thanks for the reply:  ok, I think I get that better: because &gt;&gt;= is defined in terms of map, it combines with the output of guard as well as the unfiltered 3&amp;#215;3, that&amp;#8217;s the piece that I wasn&amp;#8217;t seeing.&lt;/p&gt;


	&lt;p&gt;I think in the description above, saying that the output of guard is &amp;#8220;boring&amp;#8221; maybe throws you off the scent a little?  It&amp;#8217;s only boring to us in that we don&amp;#8217;t need a variable bound to it, but it still participates in the join.&lt;/p&gt;</description>
      <pubDate>Thu, 19 Apr 2007 05:58:43 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f99e078d-e41f-47c3-91cc-1172031442db</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-398</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;&lt;span class="caps"&gt;Y15MMY&lt;/span&gt;: Your 15 minutes may vary. ;-)&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;choose&lt;/code&gt; function does nothing but make the code more readable; it&amp;#8217;s not actually needed, not even for the type declaration.&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;guard&lt;/code&gt; is fairly sneaky. If the condition is true, it chooses a dummy value from a single-element list and throws it away. If the condition is false, though, it &amp;#8220;chooses&amp;#8221; an element from an empty list.&lt;/p&gt;


	&lt;p&gt;Imagine, for a moment, the guard condition is always false. We bind &lt;code&gt;x&lt;/code&gt; to one of 3 values, and &lt;code&gt;y&lt;/code&gt; to one of 3 values, giving us 3&amp;times;3=9 different possible answers.&lt;/p&gt;


	&lt;p&gt;If we imagine that the &lt;code&gt;guard&lt;/code&gt; condition is always false, it would choose from 0 possibilities, giving us 3&amp;times;3&amp;times;0=0 possible answers. Do you see how the empty choice suppresses answers? It doesn&amp;#8217;t have to effect the &lt;code&gt;return&lt;/code&gt; statement directly, because we never make it there.&lt;/p&gt;


	&lt;p&gt;Of course, if the &lt;code&gt;guard&lt;/code&gt; is only false &lt;i&gt;some&lt;/i&gt; of the time, then it only suppresses certain answers.&lt;/p&gt;


	&lt;p&gt;I hope this helps! Please don&amp;#8217;t hesitate to ask more questions.&lt;/p&gt;</description>
      <pubDate>Wed, 18 Apr 2007 08:35:25 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:322a2bca-6d8d-482c-bc20-b12524c53b4f</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-396</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by osfameron</title>
      <description>&lt;p&gt;Your 15 minutes are not my 15 minutes ;-)&lt;/p&gt;


	&lt;p&gt;Some things are still unclear: like why you need to use &amp;#8220;choose [1,2,3]&amp;#8221; given that that just evaluates to [1,2,3].  I have a feeling that might be important though?&lt;/p&gt;


	&lt;p&gt;Still, working through the code bit by bit is very helpful, and I &lt;strong&gt;almost&lt;/strong&gt; understand some of it now&amp;#8230;  though I am still having problems with the guard &amp;#8211; I don&amp;#8217;t understand how it affects the following return statement.&lt;/p&gt;


	&lt;p&gt;I will give another &amp;#8220;15 minutes&amp;#8221; to this tonight if I get a chance&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Wed, 18 Apr 2007 05:21:34 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:41b8768a-0439-46f7-bae5-d18f81f93224</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-395</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;Initial algebras are definitely interesting! And they &lt;i&gt;are&lt;/i&gt; related to monads, at least according to Edmund Robinson’s &lt;a href="http://www.dcs.qmul.ac.uk/tech_reports/RR-02-01.pdf"&gt;Variations on Algebra: monadicity and generalisations of equational theories&lt;/a&gt; (which I haven&amp;#8217;t finished reading yet).&lt;/p&gt;


	&lt;p&gt;A monad is a triple (&lt;i&gt;M&lt;/i&gt;,&amp;eta;,&amp;mu;), where &lt;i&gt;M&lt;/i&gt; is a functor, and &amp;eta;: &lt;i&gt;a&lt;/i&gt; &amp;rarr; &lt;i&gt;M a&lt;/i&gt; and &amp;mu;: &lt;i&gt;M (M a)&lt;/i&gt; &amp;rarr; &lt;i&gt;M a&lt;/i&gt; are natural transformations.&lt;/p&gt;


	&lt;p&gt;A monad morphism is a transformation from one monad to another, e.g., (&lt;i&gt;M&lt;/i&gt;,&amp;eta;,&amp;mu;) &amp;rarr; (&lt;i&gt;M&amp;prime;&lt;/i&gt;,&amp;eta;&amp;prime;,&amp;mu;&amp;prime;). And you can build various interesting algebras by composing monad morphisms.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s the bit I still haven&amp;#8217;t wrapped my brain completely around. :-)&lt;/p&gt;</description>
      <pubDate>Sat, 31 Mar 2007 12:03:44 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:7857c33e-794f-48e6-b3ac-6d5289e663ce</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-383</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Miles Gould</title>
      <description>&lt;p&gt;&lt;i&gt;A friend of mine claims he didn’t truly understand monads until he understood join.&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s a reason why category theorists invariably define monads in terms of join rather than bind!&lt;/p&gt;


	&lt;p&gt;As for your question about monads and algebra: I don&amp;#8217;t really understand monad transformers myself, so can&amp;#8217;t help with that bit, but there is indeed a deep connection between monads and algebraic theories. Any standard category theory book should help you here &amp;#8211; try Borceux&amp;#8217;s Handbook of Categorical Algebra. Or just google for &amp;#8220;category theory lecture notes&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;I found enlightenment came from considering this: an /algebra/ for a monad T on a category C is an object A and a morphism a:TA-&gt;A, satisfying some obvious compatibility conditions with eta and mu. Now, what is an algebra for the List monad, also known as the &amp;#8220;free monoid&amp;#8221; monad? How about the free group monad?&lt;/p&gt;


	&lt;p&gt;Sorry if I&amp;#8217;m teaching you to suck eggs here&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Fri, 30 Mar 2007 13:59:34 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f5593070-d74e-4ce4-ba3d-583b025853bd</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-382</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;Yeah, I was reading that yesterday evening! I recommended it highly for anybody who&amp;#8217;s into backtracking monads.&lt;/p&gt;</description>
      <pubDate>Wed, 14 Mar 2007 14:53:12 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e0fc20e1-164f-4937-bdc0-3b9bed2f41c0</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-365</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Michael</title>
      <description>&lt;p&gt;Nice article, Eric.&lt;/p&gt;


	&lt;p&gt;Another fun citation of type &amp;#8220;If you like the backtracking monad&amp;#8230;&amp;#8221; is Oleg Kiselyov&amp;#8217;s paper:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://okmij.org/ftp/Computation/monads.html#LogicT"&gt;http://okmij.org/ftp/Computation/monads.html#LogicT&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 14 Mar 2007 10:24:08 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:22f0df9a-c229-4d62-a739-bae38d6e8026</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-364</link>
    </item>
    <item>
      <title>"Monads in 15 minutes: Backtracking and Maybe" by Eric</title>
      <description>&lt;p&gt;petekaz: Yup, that&amp;#8217;s the tricky bit.&lt;/p&gt;


&lt;code&gt;guard&lt;/code&gt; returns either &lt;code&gt;[()]&lt;/code&gt; (if is succeeds), or &lt;code&gt;[]&lt;/code&gt; (if it fails).

	&lt;p&gt;So if the &lt;code&gt;guard&lt;/code&gt; succeeds, you can imagine it as:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-comment'&gt;-- Only one choice.  Pick it and&lt;/span&gt;
&lt;span class='hs-comment'&gt;-- continue.&lt;/span&gt;
&lt;span class='hs-definition'&gt;choose&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;...and if it fails:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-comment'&gt;-- No choices, so just give up with&lt;/span&gt;
&lt;span class='hs-comment'&gt;-- this branch of the computation.&lt;/span&gt;
&lt;span class='hs-definition'&gt;choose&lt;/span&gt; &lt;span class='hs-conid'&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If we go back to the &lt;code&gt;map&lt;/code&gt; example, we can see how it works:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-varop'&gt;&amp;gt;&lt;/span&gt; &lt;span class='hs-varid'&gt;map&lt;/span&gt; &lt;span class='hs-varid'&gt;guard&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;True&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;False&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;False&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;True&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt; &lt;span class='hs-conid'&gt;[]&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt; &lt;span class='hs-conid'&gt;[]&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;When we call &lt;code&gt;join&lt;/code&gt;, two branches of the computation disappear entirely:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-varop'&gt;&amp;gt;&lt;/span&gt; &lt;span class='hs-varid'&gt;join&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;map&lt;/span&gt; &lt;span class='hs-varid'&gt;guard&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;True&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;False&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;False&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-conid'&gt;True&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
&lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt; &lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So where are the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; in this example? Well, they&amp;#8217;re the arguments of the anonymous functions in my &lt;a href="http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-356"&gt;previous comment&lt;/a&gt;, so they&amp;#8217;ll be available when we need them in the final step. (It might help to read about &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closures&lt;/a&gt; if none of this makes any sense at all.)&lt;/p&gt;


	&lt;p&gt;Alternatively, are you familiar with list comprehensions? If so, this program is equivalent to:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;|&lt;/span&gt;
 &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;1&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;2&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;3&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;
 &lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;4&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;5&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;6&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;
 &lt;span class='hs-varid'&gt;ignored&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;&amp;lt;-&lt;/span&gt;
   &lt;span class='hs-keyword'&gt;if&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-varop'&gt;*&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-varop'&gt;==&lt;/span&gt; &lt;span class='hs-num'&gt;8&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
     &lt;span class='hs-keyword'&gt;then&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-conid'&gt;()&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
     &lt;span class='hs-keyword'&gt;else&lt;/span&gt; &lt;span class='hs-conid'&gt;[]&lt;/span&gt;
 &lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If &lt;code&gt;x*y&lt;/code&gt; doesn&amp;#8217;t equal &lt;code&gt;8&lt;/code&gt;, then there are no values to pick from for &lt;code&gt;ignored&lt;/code&gt;, and the final &lt;code&gt;(x,y)&lt;/code&gt; won&amp;#8217;t be computed.&lt;/p&gt;


	&lt;p&gt;Anyway, I hope one of these perspectives will help you puzzle it out!&lt;/p&gt;</description>
      <pubDate>Tue, 13 Mar 2007 21:11:01 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:56e72a4d-270c-4ebe-97a4-3c5961e82e8d</guid>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes#comment-363</link>
    </item>
    <item>
      <title>Monads in 15 minutes: Backtracking and Maybe</title>
      <description>&lt;p&gt;This morning, a programmer visited #haskell and asked how to implement
&lt;a href="http://www.randomhacks.net/articles/2005/10/11/amb-operator"&gt;backtracking&lt;/a&gt;.  Not surprisingly, most of the answers involved
monads.  After all, monads are ubiquitous in Haskell: They&amp;#8217;re used for IO,
for &lt;a href="http://www.randomhacks.net/articles/2007/02/22/bayes-rule-and-drug-tests"&gt;probability&lt;/a&gt;, for &lt;a href="http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways-to-report-errors"&gt;error reporting&lt;/a&gt;, and even for &lt;a href="http://sigfpe.blogspot.com/2007/03/monads-vector-spaces-and-quantum.html"&gt;quantum
mechanics&lt;/a&gt;.  If you program in Haskell, you&amp;#8217;ll
probably want to understand monads.  So where&amp;#8217;s the best place to start?&lt;/p&gt;

&lt;p&gt;A friend of mine claims he didn&amp;#8217;t truly understand monads until he
understood &lt;code&gt;join&lt;/code&gt;.  But once he figured that out, everything was
suddenly obvious.  That&amp;#8217;s the way it worked for me, too.  But relatively
few monad tutorials are based on &lt;code&gt;join&lt;/code&gt;, so there&amp;#8217;s an open niche in &lt;a href="http://www.google.com/search?q=monad+tutorial"&gt;a crowded market&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This monad tutorial uses &lt;code&gt;join&lt;/code&gt;.  Even better, it attempts to
cram everything you need to know about monads into 15 minutes.  (Hey, everybody needs a gimmick, right?)&lt;/p&gt;

&lt;h3&gt;Backtracking: The lazy way to code&lt;/h3&gt;

&lt;p&gt;We begin with a &lt;a href="http://www.randomhacks.net/articles/2005/10/11/amb-operator"&gt;backtracking constraint solver&lt;/a&gt;.  The idea: Given
possible values for &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, we want to pick
those values which have a product of 8:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-definition'&gt;solveConstraint&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;=&lt;/span&gt; &lt;span class='hs-keyword'&gt;do&lt;/span&gt;
  &lt;span class='hs-varid'&gt;x&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='hs-varid'&gt;choose&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;1&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;2&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;3&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
  &lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='hs-varid'&gt;choose&lt;/span&gt; &lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-num'&gt;4&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;5&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;6&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
  &lt;span class='hs-varid'&gt;guard&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-varop'&gt;*&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt; &lt;span class='hs-varop'&gt;==&lt;/span&gt; &lt;span class='hs-num'&gt;8&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
  &lt;span class='hs-varid'&gt;return&lt;/span&gt; &lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-varid'&gt;x&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-varid'&gt;y&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Every time &lt;code&gt;choose&lt;/code&gt; is called, we save the current program
state.  And every time &lt;code&gt;guard&lt;/code&gt; fails, we backtrack to a saved
state and try again.  Eventually, we&amp;#8217;ll hit the right answer:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='hs-varop'&gt;&amp;gt;&lt;/span&gt; &lt;span class='hs-varid'&gt;take&lt;/span&gt; &lt;span class='hs-num'&gt;1&lt;/span&gt; &lt;span class='hs-varid'&gt;solveConstraint&lt;/span&gt;
&lt;span class='hs-keyglyph'&gt;[&lt;/span&gt;&lt;span class='hs-layout'&gt;(&lt;/span&gt;&lt;span class='hs-num'&gt;2&lt;/span&gt;&lt;span class='hs-layout'&gt;,&lt;/span&gt;&lt;span class='hs-num'&gt;4&lt;/span&gt;&lt;span class='hs-layout'&gt;)&lt;/span&gt;&lt;span class='hs-keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;#8217;s build this program step-by-step in Haskell.  When we&amp;#8217;re done, we&amp;#8217;ll
have a monad.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 12 Mar 2007 19:39:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3d842a23-3d7f-4ebf-877b-352ac33b863d</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2007/03/12/monads-in-15-minutes</link>
      <category>Haskell</category>
      <category>Monads</category>
      <category>Math</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/353</trackback:ping>
    </item>
  </channel>
</rss>
