<div dir="ltr">The larger point is this: should we have applicative functions for every higher order function, for every data type? For example, one could make an argument for having Map.alterA in addition to Map.alter, because without alterA one would have to use a combination of lookup and insert, which could be slower, to achieve the same effect.<div><br></div><div>The obvious downside is the explosion of functions in the API, which is even worse due to their already being lazy and strict versions of most higher-order function (i.e. now we'd have to have 2*2 versions of every function). This seems like a failure in composability and abstraction. Until we've figured out a way to deal with this general issue that doesn't involve duplicating tons of code and swelling the API, I've been pushing back on changes like this.</div><div><br></div><div>In this particular case, having to go via lists might hurt performance a bit, but might still be better than the other alternative.</div><div><br></div><div>As one of the maintainers of the containers package these are the kind of issues I have to consider*.</div><div><br></div><div>* This is by the way one of the reasons that it's important for packages to have dedicated maintainers, so make sure proposed changes are considered in the larger context of the health and evolution of the package as a whole.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 30, 2014 at 12:52 PM, Artyom <span dir="ltr"><<a href="mailto:yom@artyom.me" target="_blank">yom@artyom.me</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I’m not sure I understand. Do you mean that |filterM| shouldn’t exist for data structures for which |filterM . toList| is as fast?<br>
<br>
If this is the case, I wish that it was at least specified in the documentation that e.g. “this function doesn’t exist because the naive composition is guaranteed to be optimised away / the faster version is actually impossible to write / etc.”. I find myself wondering way too often whether some piece of code I’ve written is a potential candidate for optimisation, and knowing in advance that the naive version is the “recommended” approach lets me not waste my time on benchmarking code which was already benchmarked by others.<span class=""><br>
<br>
On 12/30/2014 08:05 PM, Johan Tibell wrote:<br>
<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
We should check that `filterM . toList` isn't as fast. That was the case for bytestring and we rejected adding filterM there for that reason.<br>
<br></span><span class="">
On Mon, Dec 29, 2014 at 6:13 AM, Edward Kmett <<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a> <mailto:<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>>> wrote:<br>
<br>
    +1 to just generalizing filterM in Data.Sequence<br>
<br>
    On Sun, Dec 28, 2014 at 12:22 AM, David Feuer<br></span><span class="">
    <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a> <mailto:<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>><u></u>> wrote:<br>
<br>
        This can be given exactly the same implementation as the one<br>
        for lists:<br>
<br>
        filterM :: (Applicative f) => (a -> f Bool) -> Seq a -> f (Seq a)<br>
        filterM p = foldr go (pure empty)<br>
          where<br></span>
            go x r = f <0.3927809241601645gt; p x <*> r<span class=""><br>
              where<br>
                f flg ys = if flg then x <| ys else ys<br>
<br>
<br>
        Bikeshed all you like over the name.<br>
        ______________________________<u></u>_________________<br>
        Libraries mailing list<br></span>
        <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a> <mailto:<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a>><span class=""><br>
        <a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/libraries</a><br>
<br>
<br>
<br>
    ______________________________<u></u>_________________<br>
    Libraries mailing list<br></span>
    <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a> <mailto:<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a>><span class=""><br>
    <a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/libraries</a><br>
<br>
<br>
<br>
<br>
______________________________<u></u>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/libraries</a><br>
</span></blockquote><div class="HOEnZb"><div class="h5">
<br>
​<br>
______________________________<u></u>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>