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