<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Nov 26, 2015 at 3:28 AM, Akio Takano <span dir="ltr"><<a href="mailto:tkn.akio@gmail.com" target="_blank">tkn.akio@gmail.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is true, but I think it's much better to avoid breaking people's<br>
code in the first place. Also, since the breakage can be silent, one<br>
will not always be able to make a fix promptly.<br></blockquote><div><br></div><div>We're not talking about making this change until we can get some warnings in place. </div><div><br></div><div>That said, in the presence of some existing combinators that have already been generalized from Monad to Applicative you may want to ensure that these definitions have been fixed already.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
><br>
> In situations where (<*>) is asymptotically more efficient than (>>=) then<br>
> the default definition in terms of (<*>) wins.<br>
<br>
</span>You are right. I hadn't thought about this.<br>
<span class=""><br>
><br>
> Right now, if you run through hackage there are lots of places where (>>)<br>
> has been manually improved but the (*>) has not -- or vice versa. We have<br>
> two places where people should apply an optimization and many have only<br>
> realized that they should optimize one or the other.<br>
><br>
> The key here is to encourage folks to actually define (*>) when it matters.<br>
<br>
</span>I understand this, but perhaps there is a way to achieve this without<br>
slowing down existing code. How about introducing a new warning<br>
(enabled with -Wall) that is triggered when a type satisfies the<br>
following 3 conditions?<br>
<br>
1. The type has a Monad instance and an Applicative instance declared<br>
in the same module, with the same set of constraints.<br>
2. (*>) is not defined as (*>) = (>>). i.e. either it has a<br>
non-trivial definition or its definition is left out.<br>
3. (>>) is not defined as (>>) = (*>). i.e. either it has a<br>
non-trivial definition or its definition is left out.<br>
<br>
This way, people can be warned when (*>) and (>>) can share an<br>
implementation but they don't.</blockquote><div><br></div><div>This is pretty much what Herbert has been working on, except with the definition biased in favor of (>>) = (*>) being expected, and the other becoming a warning as that definition blows up when and if we later move (>>) out of the class.</div><div><br></div><div>-Edward</div></div></div></div>