0

Look at my code. ghci told that

No instance for (Applicative M) arising from the superclasses of an instance declaration In the instance declaration for ‘Monad M’

I don't understand this error, and I don't know how to fix it. Could you help me ?

newtype M a = StOut (Stack -> (a, Stack, String))

unStOut (StOut f) = f
--unStout is used to extract the emeded function from monadic capsule

instance Monad M where
    return x = StOut (\n -> (x, n, ""))
    e >>= f = StOut (\n ->  let     (a, n1, s1) = (unStOut e) n
                                    (b, n2, s2) = (unStOut (f a)) n1
                            in      (b, n2, s1++s2))
  • 2
    http://stackoverflow.com/questions/31652475/defining-a-new-monad-in-haskell-raises-no-instance-for-applicative/31652592#31652592 Basically, the rules changed in GHC 7.10 – MathematicalOrchid Apr 13 '16 at 10:43

2 Answers2

5

The error is exactly what it says: you neglected to give M an applicative instance.

Every monad is an applicative functor. By historical accident, it was in the past not required to make this fact explicit, but this lead to all kinds of inconveniences when writing generic code. The omission has since been fixed, so now to define a Monad instance you must first also define Functor and Applicative instances.

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • Can you give more details ? –  Apr 13 '16 at 10:50
  • You mean, explain how to define the `Functor` and `Applicative` instances for `M`? I could, but that's a good exercise to do yourself. Just look at the types. `fmap` is usually very simple to implement (in fact, the `-XDeriveFunctor` extension can do it for you), `pure` is the same as `return`. The only tricky one is `<*>`, but that should also be doable. (If you can't be bothered to define it yourself: you can always use [`(<*>) = ap`](http://hackage.haskell.org/package/base/docs/Control-Monad.html#v:ap), if the monad instance is finished already.) – leftaroundabout Apr 13 '16 at 11:43
1

Checkout definition of Monad. Long story short - in order to become Monad, M must be Applicative. Which in turns require M to be Functor.

class Applicative m => Monad m where
class Functor f => Applicative f where
class Functor f where

So this is what the error says.

d12frosted
  • 1,280
  • 12
  • 33