I always define Functor instances, so fmap is already covered, leaving me with a simpler join vs a more complicated bind (comparing complexity of interface, specification and implementation).<br><br>  - Conal<br><br><div class="gmail_quote">

On Sun, Jan 9, 2011 at 6:16 PM, Iavor Diatchki <span dir="ltr">&lt;<a href="mailto:iavor.diatchki@gmail.com">iavor.diatchki@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

Hello,<div>In my experience, defining monads in terms of &quot;fmap&quot; and &quot;join&quot; leads to code duplication.  The examples we have seen in this thread---so far---are a bit misleading because they compare a partial implementation of a monad (join without fmap) with a complete implementation (bind).  Here is an example of what I mean:</div>


<div><br></div><div><div>data SP a               = PutChar Char (SP a)</div><div>                        | GetChar (Char -&gt; SP a)</div><div>                        | Return a</div><div><br></div><div>fmapSP :: (a -&gt; b) -&gt; (SP a -&gt; SP b)</div>


<div>fmapSP f (PutChar c sp) = PutChar c (fmapSP f sp)</div><div>fmapSP f (GetChar k)    = GetChar (\c -&gt; fmapSP f (k c))</div><div>fmapSP f (Return a)     = Return (f a)</div><div><br></div><div>joinSP :: SP (SP a) -&gt; SP a</div>


<div>joinSP (PutChar c sp)   = PutChar c (joinSP sp)</div><div>joinSP (GetChar k)      = GetChar (\c -&gt; joinSP (k c))</div><div>joinSP (Return sp)      = sp</div><div><br></div><div>bindSP :: (a -&gt; SP b) -&gt; (SP a -&gt; SP b)</div>


<div>bindSP f (PutChar c sp) = PutChar c (bindSP f sp)</div><div>bindSP f (GetChar k)    = GetChar (\c -&gt; bindSP f (k c))</div><div>bindSP f (Return a)     = f a</div><div><br></div></div><div>I chose this example because I think that it illustrates nicely how the three operators work, I hope that other readers find it useful.</div>


<div><br></div><div>2011/1/9 Conal Elliott <span dir="ltr">&lt;<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>&gt;</span></div><div><div><div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">


* The familiarity advantage of (&gt;&gt;=) is a historical accident. I like to see the language improve over time, rather than accumulate accidents.<br></blockquote><div><br></div></div><div>I would be surprised if choosing &quot;&gt;&gt;=&quot; was an accident: it seems more likely that it was chosen because it matches a commonly occurring pattern in functional programs, and abstraction is all about giving names to common patterns.  I completely agree with the sentiment of your second sentence but I think that adding &quot;join&quot; to the Monad class would be an example of &quot;accumulating an accident&quot; rather then simplifying things.</div>


<div><br></div><div>-Iavor</div><div> </div></div></div></div>
</blockquote></div><br>