threadCode :: IO ()
threadCode = catch (print notReallyPure) outerHandler
where
outerHandler :: SomeException -> IO ()
outerHandler e = logMsg $ "Outer handler: " ++ show e
notReallyPure :: Integer
notReallyPure = unsafePerformIO $
catchRethrow (go 10) innerHandler
where
go :: Integer -> IO Integer
go 0 = return 1234
go n = do logMsg (show n)
threadDelay 100000
go (n - 1)
innerHandler :: SomeException -> IO Integer -> IO Integer
innerHandler e rethrow = do
logMsg $ "Inner handler: " ++ show e
rethrow
logMsg :: String -> IO ()
logMsg str = do
tid <- myThreadId
putStrLn $ show tid ++ ": " ++ str
It should be the case that when thread a1 gets interrupted, thread a2 can continue evaluating the notReallyPure thunk without getting either an exception and without redoing any work. In other words, the output of this main should look like