我有一个函数调用IO
类型的函数和Either String a
类型的函数。
我想在do notation中组合效果,这样我就可以在必要时解包IO
,同时在我遇到的第一个Left
时中止计算。
这是一个非常简单的例子,你可以帮我解决一下吗? (runEitherT的使用是可选的。但我认为如果你使用普通,你将无法使用MonadError
和MonadIO
功能。
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
答案 0 :(得分:2)
部分
p' <- return $ errorf p
看起来不对。在这里,return
在EitherT 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