<div dir="ltr">Given the long discussion we've had here, I'll make a call from the standpoint of the CLC and say we'd happily accept a patch that added them.<div><br></div><div>-Edward</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 14, 2016 at 2:38 PM, Conal Elliott <span dir="ltr"><<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Any recent thoughts on adding liftA4 and liftA5 to Control.Applicative?</div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Sat, Nov 8, 2014 at 11:39 AM, Edward Kmett <span dir="ltr"><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><div>We have two competing tensions that have been guiding the work so far, which is scattered across a few dozen different proposals and patches in Phab and is alarmingly intricate to detail.</div><div><br></div>We've generally been guided by the notion you suggest here. In the wake of the AMP, the 'M' suffix really comes to mean the minimal set of effects needed to get the effect. This lets us generalize large numbers of combinators in Control.Monad (e.g. when/unless/guard) to 'just work' in more contexts.<div><br></div><div>However, we also have to balance this carefully against two other concerns:</div><div><br></div><div>1.) Not breaking user code silently in undetectable ways.</div><div><br></div><div><div>This is of course the utmost priority. It guides much of the AMP, including the 'backwards' direction of most of the dependencies. e.g. The reality is a large number of folks wrote (*>) = (>>) in their code, so e.g. if we defined (>>) = (*>), we'd get a large chunk of existing production code that just turns into infinite loops. We can always do more later as we find it is safe, but "first do no harm."</div><div><br></div></div><div>2.) Not introducing rampant performance regressions.</div><div><br></div><div>David Feuer has been spending untold hours on this, and his work there is a large part of the source of endless waves of proposals he's been putting forth.</div><div><br></div><div>Considering `liftM2` as 'redundant' from `liftA2` can be dangerous on this front.</div><div><br></div><div>The decision of if we can alias liftM3 to liftA3 needs to be at least <i>partially</i> guided by the question of whether the latter is a viable replacement in practice. I'm not prepared to come down on one side of that debate without more profiling data.</div><div><br></div><div>Adding liftA4, liftA5 runs afoul of neither of these caveats. Aliasing liftMn to liftAn is something that <i>potentially</i> runs afoul of the latter, and is something that we don't have to do in a frantic rush. The world won't end if we play it safe and don't get to it in time for 7.10.</div><span><font color="#888888"><div><br></div><div>-Edward</div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Nov 8, 2014 at 7:42 AM, Andreas Abel <span dir="ltr"><<a href="mailto:abela@chalmers.se" target="_blank">abela@chalmers.se</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I am a bit alert about this discussion because it seems that we have quite different ideas about how the AMP implementation should affect the base libraries.<br>
<br>
1. Where can we see and discuss the proposed changes?<br>
<br>
Not on <a href="https://www.haskell.org/haskellwiki/Functor-Applicative-Monad_Proposal" target="_blank">https://www.haskell.org/<u></u>haskellwiki/Functor-<u></u>Applicative-Monad_Proposal</a><br>
<br>
Not on <a href="https://ghc.haskell.org/trac/ghc/ticket/9586" target="_blank">https://ghc.haskell.org/trac/<u></u>ghc/ticket/9586</a><br>
<br>
2. Imho, the reasonable thing is to<br>
<br>
  rewrite all of F/A/M base functions such that they use the minimal F/A/M constraints.<br>
<br>
This of course includes<br>
<br>
  liftM  :: (Functor m) => (a -> b) -> m a -> m b<br>
  liftM2 :: (Applicative m) => (a -> b -> c) -> m a -> m b -> m c<br>
<br>
and sequence and friends even if the M postfix can then "only explained historically" (HT).<br>
<br>
One can say "M" stands for "effectful", but the minimal type class to realize the effect is chosen from F/A/M.<br>
<br>
If we burn bridges, we should do it properly.<br>
<br>
Cheers,<br>
Andreas<span><br>
<br>
<br>
On 07.11.2014 20:35, Edward Kmett wrote:<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
I don't want them for rewriting liftM4 and liftM5, I want them in their<br>
own right.<br>
<br>
It doesn't do anyone any good to just have random asymmetries in the API<br>
like that.<br>
<br>
It just means a user goes to reach for a tool, doesn't find it and<br>
flails around.<br>
<br>
-Edward<br>
<br>
On Fri, Nov 7, 2014 at 1:37 PM, John Lato <<a href="mailto:jwlato@gmail.com" target="_blank">jwlato@gmail.com</a><br></span><span>
<mailto:<a href="mailto:jwlato@gmail.com" target="_blank">jwlato@gmail.com</a>>> wrote:<br>
<br>
    I still don't think it's worth adding liftA4 and liftA5 just so that<br>
    liftM4+ can be rewritten.<br>
<br>
    Very weakly -0.1<br>
<br>
    On Fri Nov 07 2014 at 10:24:27 AM David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a><br></span><span>
    <mailto:<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>><u></u>> wrote:<br>
<br>
        Another point: using `liftA` or `liftM`, specialized to the<br>
        relevant type, may reduce code size in some cases. With f <$> a<br>
        <*> b <*> c and such, you have to hope that you either get some<br>
        benefit from the inlining or that CSE is able to save you from<br>
        the duplication.<br>
<br>
        On Fri, Nov 7, 2014 at 7:47 AM, Jacques Carette<br></span><span>
        <<a href="mailto:carette@mcmaster.ca" target="_blank">carette@mcmaster.ca</a> <mailto:<a href="mailto:carette@mcmaster.ca" target="_blank">carette@mcmaster.ca</a>>> wrote:<br>
<br>
            On 2014-11-07 5:30 AM, Henning Thielemann wrote:<br>
<br>
<br>
                On Fri, 7 Nov 2014, Andreas Abel wrote:<br>
<br>
                    I hope the same happens for sequence, mapM and the like!<br>
<br>
                      sequence :: (Applicative m) => [m a] -> m [a]<br>
                      sequence = foldr (\ x xs -> (:) <$> x <*> xs)<br>
                    (pure [])<br>
<br>
<br>
                Actually, this is an example, where liftA2 shows its<br>
                advantage:<br>
<br>
                   sequence = foldr (liftA2 (:)) (pure [])<br>
<br>
                This looks much clearer to me than decoding the mixture<br>
                of infix and uninfixed infix operators. It simply says,<br>
                that 'sequence' is like 'id = foldr (:) []' but with<br>
                everything lifted to an applicative functor.<br>
<br>
<br>
            I agree.  I have lots of code which looks really clean<br>
            because I can use liftA2 (and even liftA3) in exactly the<br>
            way above.  Having to eta expand everything obscures the<br>
            real meat of what is going on.<br>
<br>
            Jacques<br>
<br></span>
            ______________________________<u></u>___________________<br>
            Libraries mailing list<br>
            <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>><br>
            <a href="http://www.haskell.org/__mailman/listinfo/libraries" target="_blank">http://www.haskell.org/__<u></u>mailman/listinfo/libraries</a><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>
        ______________________________<u></u>___________________<br>
        Libraries mailing list<br>
        <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>><br>
        <a href="http://www.haskell.org/__mailman/listinfo/libraries" target="_blank">http://www.haskell.org/__<u></u>mailman/listinfo/libraries</a><span><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>
    ______________________________<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>><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>
</blockquote><div><div>
<br>
-- <br>
Andreas Abel  <><      Du bist der geliebte Mensch.<br>
<br>
Department of Computer Science and Engineering<br>
Chalmers and Gothenburg University, Sweden<br>
<br>
<a href="mailto:andreas.abel@gu.se" target="_blank">andreas.abel@gu.se</a><br>
<a href="http://www2.tcs.ifi.lmu.de/~abel/" target="_blank">http://www2.tcs.ifi.lmu.de/~<u></u>abel/</a><br>
</div></div></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
</div></div><a href="http://www.haskell.org/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://www.haskell.org/mailman/listinfo/libraries</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div>