So8*_*res 5 monads haskell monad-transformers
我有以下monad转换器来处理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
Run Code Online (Sandbox Code Playgroud)
它运行得相当好,因为我可以Error使用自定义类进行实例化,并且具有非常灵活的方法来处理错误.
fail但是,有点傻,因为它是类型String -> EitherT e m,String限制可能是一种令人讨厌的创建错误的方法.我最终得到了很多:
instance Error BazError where
strMsg "foo" = FooError -- oh look we have no error context
strMsg "bar" = BarError -- isn't that nice
Run Code Online (Sandbox Code Playgroud)
我想要做的是创建一个新的函数,比如fail类型,a -> e以便我可以删除(Error e)限制.fail当monad堆栈变大时,特别方便,就像我最终一样
EitherT BazError (StateT [BazWarning] IO) Foo
Run Code Online (Sandbox Code Playgroud)
有没有办法创建一个fail与限制较少的类型具有相同行为的函数?或者fail使用深度haskell黑魔法实现?
好吧,fail如果你在一个do块中有一个模式匹配失败,就会被调用,就好像你有Just x <- something和something结果一样Nothing.除此之外,fail是一个普通的功能.
对于strMsg "foo" = FooError等问题,是否throwError为您的用例提供了更好的界面?