proposal #3335: make some Applicative functions into methods, and split off Data.Functor

David Menendez dave at
Mon Jun 29 18:01:28 EDT 2009

On Mon, Jun 29, 2009 at 4:31 PM, Ross Paterson<ross at> wrote:
> On Mon, Jun 29, 2009 at 02:37:56PM -0400, David Menendez wrote:
>> How about liftA2?
> 2 is a scary number.  Do you have an example in mind where a customized
> liftA2 would be a big win?

I don't know about a big win, but my preference for Applicative has
always been to define <*> and liftA2 as co-primitives, like so:

class Functor f => Applicative f where
    pure :: a -> f a
    liftA2 :: (a -> b -> c) -> f a -> f b -> f c
    (<*>) :: f (a -> b) -> f a -> f b

    (<*>) = liftA2 ($)
    liftA2 f a b = fmap f a <*> b

This is how the old arrows package defined Sequence, one of the
precursors to Applicative., and it's analogous to the argument that
>>= and join should both be members of Monad.

Back in 2006 I pointed out that a custom liftA2 would be sufficient to
fix frisby's problems with *> and <*.


Specifically, if liftA2 is defined like so:

    liftA2 f (P a) (P b) = P $ PMap (uncurry f) (Then a b)

and (*>) is defined using liftA2,

    (*>) = liftA2 (const id)

then (*>) is naturally the same as Frisby's custom (->>), without the
need for a custom definition.

Dave Menendez <dave at>

More information about the Libraries mailing list