<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Jun 25, 2014, at 12:52 AM, John Lato <<a href="mailto:jwlato@gmail.com">jwlato@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><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>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">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">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><div><br></div><div>Richard</div></div></body></html>