Rob*_*gar 1 haskell exception-handling monad-transformers
我正在尝试使用ExceptTmonad转换器来捕获函数抛出的任何异常,如下所示:
import Control.Exception
import Control.Monad.Trans.Except
badFunction :: ExceptT SomeException IO ()
badFunction = throw DivideByZero
main :: IO ()
main = do
r <- runExceptT badFunction
case r of Left _ -> putStrLn "caught error"
Right _ -> putStrLn "nope, didn't catch no error"
Run Code Online (Sandbox Code Playgroud)
......但异常幸福地过得很快.我究竟做错了什么?
编辑:澄清一下,目的是捕获函数抛出的任何异常,无论异常是如何抛出的.如果它有任何区别,那么真正的函数调用位于相当深的monad变换器堆栈的底部.我不介意丢失抛出的字符串之类的东西(糟糕的程序员!).
首先,您捕获运行时异常.它可以通过使用monad-control(和lifted-base)或exceptions.迈克尔斯诺曼有一篇很好的文章比较两者:例外和monad变形金刚
其次,您将捕获的异常嵌入ExceptT.
这是完整的工作代码:
import Control.Exception.Lifted
import Control.Monad.Trans.Except
badFunction :: ExceptT SomeException IO ()
badFunction = throw DivideByZero
intercept
:: ExceptT SomeException IO a
-> ExceptT SomeException IO a
intercept a = do
r <- try a
case r of
Right x -> return x
Left e -> throwE e
main :: IO ()
main = do
r <- runExceptT $ intercept badFunction
case r of Left _ -> putStrLn "caught error"
Right _ -> putStrLn "nope, didn't catch no error"
Run Code Online (Sandbox Code Playgroud)
更紧凑(但可能稍微不那么明显)的定义intercept是
intercept
:: ExceptT SomeException IO a
-> ExceptT SomeException IO a
intercept = handle throwE
Run Code Online (Sandbox Code Playgroud)