给定以下内容:
> (liftM2 fromMaybe) (ioError $ userError "OOPS") (return $ Just "ok")
ghci给我
*** Exception: user error (OOPS)
当然,fromMaybe函数是正确的:
> (liftM2 fromMaybe) (return $ "not me") (return $ Just "ok")
"ok"
但似乎IO操作正在被执行,然后被丢弃:
> (liftM2 fromMaybe) (putStrLn "computing.." >> "discarded") (return $ Just "ok")
computing..
"ok"
为什么会发生这种情况?有没有办法使IO单子变得更懒惰?
具体而言,针对 value :: IO (Maybe a)
,有没有一种简洁明了的方法来表达?
result <- (liftM2 fromMaybe) err value
并且将其解压缩并返回结果或相应地抛出IOError?
Maybe
值,然后第一层的配置函数可以使用像sequence
、<$>
和<*>
这样的方法将它们合并在一起,或者根据需要单独处理每个潜在的错误。这是一个品味问题,但我认为,在Haskell中,错误几乎总是不好的想法,因为我们有强大的抽象使我们能够组合Maybe
。throw/catch控制流机制不符合Haskell鼓励的FP风格。 - Dan Burton