1

I try to write this:

data A=A Int deriving Show

instance Monad A where
 return x=A x
 A x>>=f=f x

main=print a where a=A 1

I learn it from the book 《Learn You a Haskell for Great Good》:

instance Monad Maybe where
 return x = Just x
 Nothing >>= f = Nothing
 Just x >>= f = f x
 fail _ = Nothing

but got error:

a.hs:3:16: error:
? Expected kind ‘* -> *’, but ‘A’ has kind ‘*’
? In the first argument of ‘Monad’, namely ‘A’
  In the instance declaration for ‘Monad A’

so how to write it? When finish, I can write

A 1>>\x->x+1

and get A 2

wang kai
  • 1,673
  • 3
  • 12
  • 21

1 Answers1

7

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?

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736