如何将多个monad效果组合到同一块中?

时间:2015-03-06 18:31:05

标签: haskell monads monad-transformers

我有一个函数调用IO类型的函数和Either String a类型的函数。

我想在do notation中组合效果,这样我就可以在必要时解包IO,同时在我遇到的第一个Left时中止计算。

这是一个非常简单的例子,你可以帮我解决一下吗? (runEitherT的使用是可选的。但我认为如果你使用普通,你将无法使用MonadErrorMonadIO功能。

entryPoint :: IO (Either String Int)
entryPoint = runEitherT foo

-- p and p' should have type Int,
-- and errorf can force the computation to abort (as can throwError) 
foo :: EitherT String IO Int
foo = do
  p <- liftIO $ iof 1
  p' <- return $ errorf p
  if p' == 2
    then throwError "No!"
    else return 1

errorf :: b -> Either String b
errorf = undefined

iof :: a -> IO a
iof = undefined

1 个答案:

答案 0 :(得分:2)

部分

p' <- return $ errorf p

看起来不对。在这里,returnEitherT String IO中构建了一个monadic值。假设errorf p = Left something正在构建的值是

p' <- EitherT (return (Right (Left something)))

以上return构建IO操作。这不是我们想要的 - 那里有一个额外的Right。我们反而想要

p' <- EitherT (return (Left something))

p' <- EitherT $ return $ errorf p