Skip to content

Instantly share code, notes, and snippets.

@monadplus
Last active February 3, 2020 22:20
Show Gist options
  • Save monadplus/75fd64dfe6898ea902d426d022ba6f5e to your computer and use it in GitHub Desktop.
Save monadplus/75fd64dfe6898ea902d426d022ba6f5e to your computer and use it in GitHub Desktop.
Control.Exception.evaluate
{-# LANGUAGE ScopedTypeVariables #-}
-- pure/return vs evaluate on try
data UserError = UserError String
deriving Show
instance Exception UserError
>>> (try . pure . throw $ UserError "die") >>= either (\(e :: SomeException) -> putStrLn "exception captured") (\a -> seq a (putStrLn "no exception"))
*** Exception: foo
-- Why the exception isn't captured ?
--
-- Because pure doesn't evaluate the argument to whnf,
-- the exception is still not evaluated and try doesn't catch it.
--
-- Then when you call either it will match the Right thunk which contains
-- an exception and throws.
-- Use Control.Exception.evaluate instead.
-- Source: https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Exception.html#v:evaluate
>>> (try . evaluate . throw $ UserError "die") >>= either (\(e :: SomeException) -> putStrLn "exception captured") (\a -> seq a (putStrLn "no exception"))
"exception captured"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment