定义Monad时出现Haskell类型错误

定义Monad时出现Haskell类型错误,haskell,monads,Haskell,Monads,我有一个类型Effect,它表示堆栈上的效果。效果可以是修改堆栈并可选地生成输出的成功效果,也可以是在堆栈失败时记住堆栈外观的错误 data Effect a = Failure a | Effect a [Int] instance Monad Effect where return s = Effect s [] (Failure debugS) >>= _ = Failure debugS (Effect oldS oldO) >>= f =

我有一个类型
Effect
,它表示堆栈上的效果。
效果
可以是修改堆栈并可选地生成输出的成功效果,也可以是在堆栈失败时记住堆栈外观的错误

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)
绑定应该连接结果(据我所知,顺序相反)。但是,目前GHC向我发出以下错误消息:

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

我是Haskell的新手,不习惯GHC的错误消息。我应该如何更正此错误?

从GHC 7.10开始,不幸的是,由于以下原因,您需要实现
Monad
Applicative
Functor

出现类型错误的原因是
>>=
的类型为:

(>>=) :: Monad m => m a -> (a -> m b) -> m b
这意味着您传入的函数返回类型
mb
。但是,由于您返回
故障调试
,这是类型
MA
,这是一种类型不匹配,因为它本质上强制
>=
符合以下要求:

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

您返回的
调试
必须是不同的。

是否有任何方法来约束
(>>=)
,使其类型签名为
(>>=)::Monad m=>ma->(a->ma)->ma
?我不确定,但我认为一种方法是将
Failure
修改为类似
data Effect a=Failure FailMsg |…
。这允许您随后通过
>=
运算符传播一些类型为
FailMsg
的数据。因为
FailMsg
不依赖于类型变量
a
,所以您不会遇到
>=
运算符类型的问题。@Challenger5不,这不会是monad。如果您想在一元操作链中保留一个类型参数,那么它应该是另一个类型参数。类似于
data Effect sa=Failure s | Effect sa[Int]
实例Monad(Effect s),其中…
但我不知道如何继续。也许会给出几个用例。@n.m.实际上我只希望
Effect
与单个类型一起使用。@challenger 5您没有或不需要monad。也许是幺半群