简体   繁体   中英

Haskell Type Error when Defining Monad

I have a type Effect which represents an effect on a stack. An Effect can either be a successful effect which modifies a stack and optionally generates output, or it can be an error that remembers how the stack looked when it failed.

data Effect a = Failure a | Effect a [Int]
instance Monad Effect where
    return s = Effect s []
    (Failure debugS) >>= _ = Failure debugS
    (Effect oldS oldO) >>= f =
        case f oldS of
            (Failure debugS) -> Failure debugS
            (Effect newS newO) -> Effect newS (newO ++ oldO)

Binding should concatenate the results (in reverse order, I am aware). However, at the moment GHC gives me the following error message:

example.hs:2:10:
    No instance for (Applicative Effect)
      arising from the superclasses of an instance declaration
    In the instance declaration for ‘Monad Effect’

example.hs:4:38:
    Couldn't match expected type ‘b’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for
            (>>=) :: Effect a -> (a -> Effect b) -> Effect b
          at example.hs:4:22
      ‘b’ is a rigid type variable bound by
          the type signature for
            (>>=) :: Effect a -> (a -> Effect b) -> Effect b
          at example.hs:4:22
    Relevant bindings include
      debugS :: a (bound at example.hs:4:14)
      (>>=) :: Effect a -> (a -> Effect b) -> Effect b
        (bound at example.hs:4:5)
    In the first argument of ‘Failure’, namely ‘debugS’
    In the expression: Failure debugS

I am new to Haskell and unused to GHC's error messages. How should I correct this error?

As of GHC 7.10, you unfortunately need to implement Monad , Applicative , and Functor due to the Functor-Applicative-Monad Proposal .

The reason you get the type error is because the type of >>= is:

(>>=) :: Monad m => m a -> (a -> m b) -> m b

This means that the function you pass in gives back type mb . However, because you give back Failure debugS , this is of type ma , which is a type mismatch, because it essentially forces the >>= to conform as:

(>>=) :: Monad m => m a -> (a -> m a) -> m a  -- Wrong!

The debugS that you return will have to be different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM