Reputation: 7139
I want to catch all exceptions in IO String function. When I run this code:
import Control.Exception.Base
handler :: SomeException -> IO String
handler _ = return "Gotta catch'em all!"
boom :: IO String
boom = return (show (3 `div` 0))
get :: IO String
get = boom `catch` handler
main :: IO()
main = do
x <- get
print x
I get
exctest: divide by zero
However this code works:
import Control.Exception.Base
handler2 :: SomeException -> IO ()
handler2 _ = print "Gotta catch'em all!"
boom2 :: IO ()
boom2 = print $ show (3 `div` 0)
main :: IO()
main = do
boom2 `catch` handler2
with result
> Gotta catch'em all!
When I change boom in first example to
boom = error "ERR"
The exception is caught ok. Why does it behave this way? What should I do to catch exception in first example?
Upvotes: 2
Views: 188
Reputation: 120711
This has nothing to do with ()
vs. other types. Note that the following also doesn't catch:
boom = return $ error "ERR"
The reason catch
won't do anything about that is that return
is lazy, thus the error isn't actually triggered by catch
, only if you try to get at the contained value.
It is for precisely this reason that the Exception
module has evaluate, which is equivalent to return
but strict.
boom :: IO String
boom = evaluate . show $ 3`div`0
Upvotes: 8