首页 文章

将错误值提升到ErrorT monad转换器

提问于
浏览
5

我想我缺少对monad变换器的基本理解,因为我发现自己编写了这段代码:

import Control.Monad.Identity
import Control.Monad.Error

liftError :: Either String Int -> ErrorT String Identity Int
liftError x = do case x of
                    Right val -> return val
                    Left err -> throwError err

gateway :: Bool -> ErrorT String Identity Int
gateway = liftError . inner

inner :: Bool -> Either String Int
inner True = return 5
inner False = throwError "test"

虽然这有效,但我认为这可以更优雅地完成 . 特别是,我正在寻找 liftError 的替代品,我认为我不应该为自己定义 .

什么是最简单的方法让 gatewayinner 一起工作而不改变他们的类型?

1 回答

  • 6

    如果您只是稍微更改类型,则根本不需要进行任何提升 .

    {-# LANGUAGE FlexibleContexts #-}
    
    gateway :: Bool -> ErrorT String Identity Int
    gateway = inner
    
    inner :: MonadError String m => Bool -> m Int
    inner True = return 5
    inner False = throwError "test"
    

    MonadError 具有 ErrorTEither 的实例,因此这样您可以使用 inner 作为两者 .

相关问题