<br><br><div class="gmail_quote">On Sun, Jun 24, 2012 at 12:27 AM, Chris Dornan <span dir="ltr">&lt;<a href="mailto:chris@chrisdornan.com" target="_blank">chris@chrisdornan.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br></div>
  * To move between functional and monadic code you have to completely<br>
rewrite the code procedurally -- its<br>
    true and (IMHO) regrettable.<br></blockquote><div><br></div><div>It&#39;s false.  do-notation is completely optional.  It merely makes it easier to extract multiple values from monadic actions, instead of the basic &quot;one value per step&quot; bind provides.   Using join and (&gt;&gt;=) is just as easy as do-notation, once you understand the idiom.</div>
<div><br></div><div>A monad is, first and foremost, a functor.  You can get at the underlying algebra while statically ensuring relevant properties, using its functorial or applicative or monadic interfaces.</div><div><br>
</div><div>For example:  consider a function that parses a string into a Foo.  It will have a type like</div><div><br></div><div>parseFoo :: String -&gt; Maybe Foo</div><div><br></div><div>Should &quot;useFoo&quot; have the type</div>
<div><br></div><div>useFoo :: Maybe Foo -&gt; Maybe Bar</div><div><br></div><div>or</div><div><br></div><div>useFoo :: Foo -&gt; Bar?</div><div><br></div><div>The maybe functor/monad encapsulates the behavior of propagating possible-undefinedness, so we are entirely justified in using its functor/monad interface to simplify our types.  There is no reason to redundantly have to pattern match on (Just foo) or (Nothing) when we can abstract the control structure away and do</div>
<div><br></div><div>useFoo &lt;$&gt; (parseFoo &quot;Foo 1&quot;) -- (&lt;$&gt; == fmap)</div><div><br></div><div>or</div><div><br></div><div>(parseFoo &quot;Foo 1&quot;) &gt;&gt;= return . useFoo</div><div><br></div><div>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Expressing procedural code<br>
functionally is as unnatural and error<br>
prone as expressing functional code procedurally in my experience -- that<br>
Haskell avoids compelling the programmer to<br>
do either within its strongly-typed functional framework is (IMHO) its great<br>
invention(*) and enduring strength.</blockquote><div><br></div><div>Haskell didn&#39;t invent monads.  They have been in use since Grothendieck&#39;s work in algebraic topology.  At least!  It is not hard to make a plausible case that the Pythagoreans had a theory of monads in mind 2500 years ago.</div>
</div>