Haskell monads和一个不';我不需要字符串

Haskell monads和一个不';我不需要字符串,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,我有以下monad transformer用于处理Haskell中的错误 instance (Monad m, Error e) => Monad (EitherT e m) where return = EitherT . return . return m >>= k = EitherT $ do a <- runEitherT m case a of Left l -

我有以下monad transformer用于处理Haskell中的错误

instance (Monad m, Error e) => Monad (EitherT e m) where
    return = EitherT . return . return
    m >>= k  = EitherT $ do
            a <- runEitherT m
            case a of
                Left  l -> return (Left l)
                Right r -> runEitherT (k r)
    fail = EitherT . return . Left . strMsg
我想做的是创建一个新函数,比如
fail
,它的类型是
a->e
,这样我就可以删除
(Error e)
限制<代码>失败在monad堆栈变大时特别方便,比如当我以

EitherT BazError (StateT [BazWarning] IO) Foo

有没有一种方法可以创建一个与
fail
具有相同行为的函数,但类型限制较少?或者
fail
是使用deep haskell dark magic实现的吗?

如果do块中的模式匹配失败,则调用
fail
,例如,如果您只有
x这篇文章可能很有用:

您的EitherT已在标准库中,名为
error
。请参阅文档:

fail
现在是一个历史奇观,可能被认为是一个设计缺陷,以及缺少
Functor a=>Monad a
约束。在
do
符号中处理失败的模式匹配只是一个有争议的特性

throwError :: MonadError e m => e -> m a

fail
最常见的替代品,但还有更多可用的替代品(见文章)。

您可能只需完全避免
fail
,除非您想自定义失败的
do
块模式匹配的行为。
throwError :: MonadError e m => e -> m a