Proposal: add liftA4 and liftA5 to match liftM4 and liftM5

Andreas Abel abela at chalmers.se
Sat Nov 8 20:39:18 UTC 2014


Thanks for your replies.

My hope for AMP was to get generalization of effectful combinators 
without requiring more identifiers (and actually freeing some, like 
making `sequenceA` and `for` obsolete).  I see that it is not so easy if 
GHC's reduction behavior has to be taken into account.

So +1 from me if you deem liftA4 and liftA5 necessary.

On 08.11.2014 21:21, David Feuer wrote:
> On Sat, Nov 8, 2014 at 2:39 PM, Edward Kmett <ekmett at gmail.com
> <mailto:ekmett at gmail.com>> wrote:
>
>     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.
>
>     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.
>
>     However, we also have to balance this carefully against two other
>     concerns:
>
>     1.) Not breaking user code silently in undetectable ways.
>
>     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."
>
>
> Indeed. I've looked at quite a few Applicative and Monad instances
> lately, and one conclusion I've come to is that it often makes *more*
> sense to define (*>) = (>>) than the other way around. In particular,
> monads like IO and ST have a (>>=) that's about as simple as anything
> remotely interesting you can do with them. In particular,
>
>    fs <*> xs = fs >>= \f -> xs >>= \x -> return (f x)
>
> is about as simple as it gets. The default definition of (*>) looks like
> this:
>
>    m *> n = (id <$ m) <*> n
>
> But these don't have particularly special Functor instances either. So
> this expands out to
>
>    m *> n = fmap (const id) m <*> n
>
> which becomes
>
>    m *> n = (m >>= (return . const id)) >>= \f -> n >>= \x -> return (f x)
>
> Can we say "ouch"? We now have to hope that GHC inlines enough to do
> anything more. If it does, it will take a few extra steps along the way.
>
> Compare this mess to (>>):
>
> m >> n = m >>= \_ -> n
>
> So I think there's a pretty clear case for (*>) = (>>) actually being
> the right thing in a lot of cases.
>
>     2.) Not introducing rampant performance regressions.
>
>     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.
>
>     Considering `liftM2` as 'redundant' from `liftA2` can be dangerous
>     on this front.
>
>
> That's definitely a valid concern, for the reasons described above.
> Everything works out nicely because of monad laws, but GHC doesn't know
> that.
>
>     The decision of if we can alias liftM3 to liftA3 needs to be at
>     least /partially/ 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.
>
>
> Yes, that makes sense. I think the problem fundamentally remains the
> same--the monadic operations ultimately need to be inlined and
> completely twisted around in order to be fast.
>
>
>     Adding liftA4, liftA5 runs afoul of neither of these caveats.
>     Aliasing liftMn to liftAn is something that /potentially/ 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.
>
>
> The more I think about it, the more right I think you are.
>
> David

-- 
Andreas Abel  <><      Du bist der geliebte Mensch.

Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden

andreas.abel at gu.se
http://www2.tcs.ifi.lmu.de/~abel/


More information about the Libraries mailing list