首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >自动将其中一个提升到ExceptT

自动将其中一个提升到ExceptT
EN

Stack Overflow用户
提问于 2016-01-04 17:55:07
回答 3查看 1.5K关注 0票数 9

假设我有一段代码(可能是误导性的):

代码语言:javascript
复制
import System.Environment (getArgs)
import Control.Monad.Except

parseArgs :: ExceptT String IO User
parseArgs =
  do
    args <- lift getArgs
    case safeHead args of
      Just admin -> parseUser admin
      Nothing    -> throwError "No admin specified"

parseUser :: String -> Either String User
-- implementation elided

safeHead :: [a] -> Maybe a
-- implementation elided

main =
  do
    r <- runExceptT parseArgs
    case r of
      Left  err -> putStrLn $ "ERROR: " ++ err
      Right res -> print res

ghc给了我以下错误:

代码语言:javascript
复制
Couldn't match expected type ‘ExceptT String IO User’
            with actual type ‘Either String User’
In the expression: parseUser admin
In a case alternative: Just admin -> parseUser admin

Either提升为ExceptT的最标准方法是什么?我觉得一定有办法,因为Either StringMonadError的一个实例。

我写了自己的提升函数:

代码语言:javascript
复制
liftEither :: (Monad m, MonadError a (Either a)) => Either a b -> ExceptT a m b
liftEither = either throwError return

但对我来说,这仍然是错误的,因为我已经在ExceptT monad转换器中工作了。

我在这里做错了什么?我应该以不同的方式构造我的代码吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-04 20:03:17

您可以将parseUser的类型概括为

代码语言:javascript
复制
parseUser :: (MonadError String m) => String -> m User 

然后,它可以在m ~ Either Stringm ~ ExceptT String m' (如果只有Monad m')上工作,而不需要任何手动提升。

要做到这一点,在parseUser的定义中,基本上是用return替换Right,用throwError替换Left

票数 10
EN

Stack Overflow用户

发布于 2018-06-07 05:36:10

如果您使用的是transformers而不是mtl,那么您可以使用Control.Error.Safe中的tryRight

代码语言:javascript
复制
tryRight :: Monad m => Either e a -> ExceptT e m a
票数 3
EN

Stack Overflow用户

发布于 2021-08-03 15:23:10

您可以在transformers (Control.Monad.Trans.Except)中使用except

except :: Monad m => Either e a -> ExceptT e m a

它被定义为ibotty在评论中建议的。

因为它不是MonadError,所以它和你的liftEither有点不同。您可以在ExceptT适用的任何地方使用它。

顺便说一句,已经有了一个liftEither,这是不同的:

liftEither :: MonadError e m => Either e a -> m a

我不认为这个对你有什么用处。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34588488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档