I'll start by introducing a concrete problem (StackOverflow guys like that). Say you define a simple type
data T a = T a
This type is a Functor
, Applicative
and a Monad
. Ignoring automatic deriving, to get those instances you have to write each one of them, even though Monad
implies Applicative
, which implies Functor
.
More than that, I could define a class like this
class Wrapper f where
wrap :: a -> f a
unwrap :: f a -> a
This is a pretty strong condition and it definitely implies Monad
, but I can't write
instance Wrapper f => Monad f where
return = wrap
fa >>= f = f $ unwrap fa
because this, for some reason, means "everything is a Monad
(every f
), only if it's a Wrapper
", instead of "everything that's a Wrapper
is a Monad
".
Similarly you can't define the Monad a => Applicative a
and Applicative a => Functor a
instances.
Another thing you can't do (which is only probably related, I really don't know) is have one class be a superclass of another one, and provide a default implementation of the subclass. Sure, it's great that class Applicative a => Monad a
, but it's much less great that I still have to define the Applicative
instance before I can define the Monad
one.
This isn't a rant. I wrote a lot because otherwise this would quickly the marked as "too broad" or "unclear". The question boils down to the title. I know (at least I'm pretty sure) that there is some theoretical reason for this, so I'm wondering what exactly are the benefits here.
As a sub question, I would like to ask if there are viable alternatives that still keep all (or most) of those advantages, but allow what I wrote.
Addition:
I suspect one of the answers might be something along the lines "What if my type is a Wrapper
, but I don't want to use the Monad
instance that that implies?". To this I ask, why couldn't the compiler just pick the most specific one? If there is an instance Monad MyType
, surely it's more specific than instance Wrapper a => Monad a
.