Jeremy Shaw wrote:
What I would prefer is:

instance (Monad f, Applicative f) => Applicative (ReaderT r f) where
    pure a = ReaderT $ const (pure a)
f <*> a = ReaderT $ \r -> ((runReaderT f r) <*> (runReaderT a r))

Right. This doesn't only go for ReaderT, it already goes for Either, too: you don't want the 'ap' implementation for <*> there either.

These are beautiful examples of how applicative style gives the caller less power, but the callee more information, allowing more information to be retained. In this case it allows you to concatenate errors using mappend.

Another example is parsing: I believe Doaitse's parsers allow more optimization if they are only used in applicative style (but I'm not sure of this).

This shows there can be several sensible implementations of a type class. You ask which instance is right--that depends entirely on what you want it to do! Setting (<*>) = ap is just one of them, one you happen to get for free if your functor is already a monad.

Hope this helps,

Martijn.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to