You can't make A
an instance of Monad
given its current definition.
The error message tells you that the compiler expects something of the kind * -> *
. This means a type that takes a type as input, like Maybe a
, IO a
, or [] a
. In other words, the type must be parametrically polymorphic.
In oder to get an intuitive sense of this, consider return
, which has the type:
return :: a -> m a
The type argument a
is unconstrained. This means that you should be able to take any value of type a
and turn it into a value of the polymorphic type.
If I give you the Boolean value False
, which A
value will you construct from it? If I give you the string "foo"
, which A
value will you construct from it? If I give you the function id
, which A
value will you construct from it?
If you want to make your type a Monad
instance, you must give it a type parameter, at least like this:
data A a = A Int deriving Show
Here, the a
type parameter is in the phantom role; it's not used, but now you're at least able to make it a Functor
. This version of A
is isomorphic to the Const functor. You can make it a Functor
and Applicative
instance, but can you make it a Monad
?