我想我缺少对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
的替代品,我认为我不应该为自己定义 .
什么是最简单的方法让 gateway
和 inner
一起工作而不改变他们的类型?
1 回答
如果您只是稍微更改类型,则根本不需要进行任何提升 .
MonadError
具有ErrorT
和Either
的实例,因此这样您可以使用inner
作为两者 .