Applicative ((->) c) methods

Carter Schonwald carter.schonwald at
Tue Nov 19 00:31:31 UTC 2019

hey Keith,
when emailing to the library list, linking to the source code you're
referring to:

can be super helpful for making sure everyone is on the same page ! (i
think i'm linking to the right code, plz confirm!)

unless the commit history indicates otherwise, i'd presume any current
choices in base are largely a product of historical reasons and or the
style of whomever wrote it most recently?

you are absolutely correct that when it comes to inlining,  "foo = \x ->
.. " will always satisfy the saturation condition to get inlined, while
"foo x = ..." will only be marked saturated when fully applied, (and this
of course ignoring how specializing the type class instances of a piece of
code behaves!)

i do generally agree that the RHS style you allude to is very handy when i
"know" that the definition should essentially simplify/partial evaluate
away to some function application and or let expression (especially if the
resulting code looks non recursive! ) to help ghc along, though excessive
inlining can be quite bad too! (Austin Seipp and Edward K have some really
good long comments on reddit etc about this, though i cant find the
particular one i'm thinking of by austin from a few years back).

one point Austin made was along the lines of: if you have to tell ghc
when/how to inline something to get good performance, this should be
treated as a bug (by and large).

though of course for core libraries interfaces/definitions/performance
critical primops, that guidance isn't necessarily the right default

I think the best approach to grounding these sorts of performance motivated
changes is to

1) write a tiny application / benchmark demonstrator with your own locally
defined / newtypy versions of both definitions you wanna compare
2) if need be, compare two versions of the same commit of ghc etc, (with
one having the proposed change set in base), and running nofib et al  to
have a statistical characterization of impact!

That said, i definitely agree with the implication that point free style
(aka partially applied ) code using the (-> r) applicative/monad
definitions, such as might be found in the lens library "over" and friends,
may or may not benefit from this sort of change. Though i suspect Eric
Mertens or Edward K or Ryan Scott might have better clarity on that

Thanks for taking the time to think about this and ask/start a discussion! '


On Mon, Nov 18, 2019 at 3:40 PM Keith <keith.wygant at> wrote:

> Just thinking for Applicative ((->) c)
> (<*) = const
> (*>) = flip const -- or \ _ x -> x
> Is it because we can rely on GHC to produce the same code from the current
> definitions?
> Also wondering why Monad uses
> f >>= k = \ r -> k (f r) r
> but Applicative uses
> (<*>) f g x = f x (g x)
> liftA2 q f g x = q (f x) (g x)
> Seems like if it's style/legibility, it should be consistent between (>>=)
> and (<*>). And if it's inlining issue, we'd want lambdas for all three.
> --Keith
> --
> Sent from my phone with K-9
> Mail._______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list