In Scalaz every Monad
instance is automatically an instance of Applicative
.
implicit val listInstance = new Monad[List] {
def point[A](a: => A) = List(a)
def bind[A, B](fa: List[A])(f: A => List[B]) = fa flatMap f
}
List(2) <*> List((x: Int) => x + 1) // Works!
Another example: Arrow
is automatically a Profunctor
.
However, in Haskell I must provide an instance of Applicative
for every Monad
again and again.
Is it possible to avoid this repetitive job?
It isn't currently possible, though it would be if you changed the existing library to support this. Turning DefaultSignatures on would let you write
class Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
default pure :: Monad f => a -> f a
default (<*>) :: Monad f => f (a -> b) -> f a -> f b
pure = return
(<*>) = ap
Then once you had implemented instance Monad M where {- ... -}
, a simple instance Applicative M
(with no where
or method definitions) would inherit these default implementations. I'm not sure why this wasn't done.
The problem comes when there are two places from which to derive the Applicative
instance. For instance, suppose m
is the type a b
where Arrow a
. Then there's an obvious instance of Applicative
from this definition as well. Which one should the compiler use? It should work out the same, of course, but Haskell has no way to check this. By making us write out the instances, Haskell at least forces us to think about the consistency of our definitions.
If you want, there's the WrappedMonad
class in Control.Applicative
, which provides all the obvious instances with a newtype
wrapper, but using WrapMonad
and unwrapMonad
all the time isn't that attractive either.