Home > database >  What is the point of the Functor -> Applicative -> Monad hierarchy
What is the point of the Functor -> Applicative -> Monad hierarchy

Time:01-03

What is the point of making Functor a super class of Applicative and Monad. Both Applicative and Monad immediately imply the only implementation of Functor that abides by the laws as far as I can tell. But rather I have to type out the same implementation of Functor every time. Is there a way to avoid doing this?

Further more Monad implies the only implementation of Applicative that abides by the laws so why make Applicative a super class of Monad? Again it makes implementing Applicative for new data types redundant.

Is there a way to make a Monad without having to implement Applicative and Functor (as its operations are already the most general). And to make an Applicative without having to implement Functor.

I see the benefit of the class hierarchy as what I just said explains the "is a" relation between them. But at the same time having to implement each is annoying. I just want to define return and >>= and get all the operations of all 3 back.

CodePudding user response:

You can get those instances this way:

import Control.Applicative
data Whatever = {- ... -} deriving (Functor, Applicative) via (WrappedMonad Whatever)

It would have been nice to add DefaultSignatures defaults to the Functor and Applicative classes at the time the compiler broke from the spec, so that you wouldn't even need to write via WrappedMonad, but now that it's done I suspect we'll never get them. Too bad.

CodePudding user response:

The cost of having to write the Applicative and Monad instances is paid only once, by the implementer. The cost of not having those instances, however, is borne by the users, time and time again. Consider a combinator which uses Applicative, such as traverse:

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

Without the superclass relationship, our choice of f being a Monad wouldn't be enough to let us use traverse. We'd end up needing a Monad-specific version of traverse (that is, mapM), and to switch from one to the other on the grounds of a distinction which is almost always irrelevant. Having Applicative as a superclass of Monad means we need not bother with that.

  • Related