Why should Applicative be a superclass of Monad?

Well, I’m not terribly satisfied with the answers given so far, but I think the comments attached to them are a bit more compelling. So I’ll summarize here:


I think there’s only one sensible Functor instance that follows from Applicative:

fmap f fa = pure f <*> fa

Assuming that’s unique, it makes sense that Functor should be a superclass of Applicative, with that law. Likewise, I think there’s only one sensible Functor instance that follows from Monad:

fmap f fa = fa >>= return . f

So again, it makes sense that Functor should be a superclass of Monad. The objection I had (and, really, still have) is that there are two sensible Applicative instances that follow from Monad and, in some specific instances, even more that are lawful; so why mandate one?

pigworker (first author on the original Applicative paper) writes:

“Of course it doesn’t follow. It’s a choice.”

(on twitter): “do-notation is unjust punishment for working in a monad; we deserve applicative notation”

duplode similarly writes:

“… it is fair to say that pure === return and (<*>) === ap aren’t laws in the strong sense that e.g. the monad laws are so …”

“On the LeftA/RightA idea: there are comparable cases elsewhere in the standard libraries (e.g. Sum and Product in Data.Monoid). The problem of doing the same with Applicative is that the power-to-weight relation is too low to justify the extra precision/flexibility. The newtypes would make applicative style a lot less pleasant to use.”

So, I’m happy to see that choice stated explicitly, justified by the simple reasoning that it makes the most common cases easier.

Leave a Comment