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

Nik*_* B. 5 monads haskell monad-transformers

我想我缺少对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"
Run Code Online (Sandbox Code Playgroud)

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

在不改变类型的情况下,最直接的制作gatewayinner合作方式是什么?

ham*_*mar 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"
Run Code Online (Sandbox Code Playgroud)

MonadError有两个实例ErrorTEither,所以这种方式,您可以使用inner两者并用.