<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jun 25, 2014 at 3:14 PM, Richard Eisenberg <span dir="ltr"><<a href="mailto:eir@cis.upenn.edu" target="_blank">eir@cis.upenn.edu</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class=""><div>On Jun 25, 2014, at 12:52 AM, John Lato <<a href="mailto:jwlato@gmail.com" target="_blank">jwlato@gmail.com</a>> wrote:</div>

<br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>The compiler makes assumptions about associativity when de-sugaring do-notation.  If the monad laws aren't followed, it's possible for these two blocks to show different behavior (given that a,b,c are all values of the misbehaved Monad instance):</div>


<div><br></div><div>> do { a; b; c }</div><div><br></div><div>> a >> b >> c</div><div><br></div><div>I think everyone can agree that this is surprising, at the very least.  Although it's not the compiler that's generating bad code here.</div>

</div></div></div></blockquote><div><br></div></div><div>As far as I know, GHC makes no assumptions about associativity, or any class-based laws. The effect John observes above is accurate, but it is a direct consequence of the design of Haskell in the Haskell 2010 Report, not any assumptions in the compiler.</div>

<div><br></div><div>Specifically, Section 3.14 (<a href="https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-470003.14" target="_blank">https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-470003.14</a>) says that `do { e; stmts }` desugars to `e >> do {stmts}`. In the case of `do { a; b; c }`, that means we get `a >> (b >> c)`. However, in Table 4.1 in Section 4.4.2 (under <a href="https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-800004.4" target="_blank">https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-800004.4</a>), we see that (>>) is *left*-associative, meaning that `a >> b >> c` means `(a >> b) >> c`.</div>

<div><br></div><div>Are the different meanings here an "assumption" of associativity? I suppose one could construe it that way, but I just see `do { a; b; c}` and `a >> b >> c` as different chunks of code with different meanings. If the monad in question upholds the associativity law, then the chunks evaluate to the same result, but they're still distinct.</div>

<span class="HOEnZb"><font color="#888888"><div><br></div></font></span></div></div></blockquote><div><br></div><div>Great explanation! Would you say that the main reason for implementing monads so >> is associative is to make sure the do notation does the "right thing"?</div>

<div><br></div><div>Monad is a notion from math which was imported into Haskell. As far as I know, the reason behind it was to give Haskell the possibility of doing IO while keeping itself pure. If there was a data type just like Moand, with >>=, >>, return and all. It behaved  exactly the same, but no one cared about identity or associativity, then it wouldn't be a monad, but it would solve the computation with side-effects thing just the same. Why was associativity and identity brought to the language as well? What is there to be gained by such a law which can't be enforced by the compiler?</div>

</div></div></div>