summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2022-02-24 17:59:12 +0100
committerSebastian Graf <sebastian.graf@kit.edu>2022-02-24 17:59:12 +0100
commit5f8bb63d6a105a196928aaf675535d699dffcb7f (patch)
tree93b5e37f285c53d9f984aa724a70892cb95e2684
parent7d426148c48d95c45ee3e5b050a4804700b08206 (diff)
downloadhaskell-wip/T19854.tar.gz
base: Improve documentation of `throwIO` (#19854)wip/T19854
Now it takes a better account of precise vs. imprecise exception semantics. Fixes #19854.
-rw-r--r--libraries/base/GHC/IO.hs26
1 files changed, 22 insertions, 4 deletions
diff --git a/libraries/base/GHC/IO.hs b/libraries/base/GHC/IO.hs
index 283020d973..f597277710 100644
--- a/libraries/base/GHC/IO.hs
+++ b/libraries/base/GHC/IO.hs
@@ -207,16 +207,34 @@ mplusIO m n = m `catchException` \ (_ :: IOError) -> n
-- Although 'throwIO' has a type that is an instance of the type of 'throw', the
-- two functions are subtly different:
--
--- > throw e `seq` x ===> throw e
--- > throwIO e `seq` x ===> x
+-- > throw e `seq` () ===> throw e
+-- > throwIO e `seq` () ===> ()
--
-- The first example will cause the exception @e@ to be raised,
-- whereas the second one won\'t. In fact, 'throwIO' will only cause
-- an exception to be raised when it is used within the 'IO' monad.
+--
-- The 'throwIO' variant should be used in preference to 'throw' to
-- raise an exception within the 'IO' monad because it guarantees
--- ordering with respect to other 'IO' operations, whereas 'throw'
--- does not.
+-- ordering with respect to other operations, whereas 'throw'
+-- does not. We say that 'throwIO' throws *precise* exceptions and
+-- 'throw', 'error', etc. all throw *imprecise* exceptions.
+-- For example
+--
+-- > throw e + error "boom" ===> error "boom"
+-- > throw e + error "boom" ===> throw e
+--
+-- are both valid reductions and the compiler may pick any (loop, even), whereas
+--
+-- > throwIO e >> error "boom" ===> throwIO e
+--
+-- will always throw @e@ when executed.
+--
+-- See also the
+-- [GHC wiki page on precise exceptions](https://gitlab.haskell.org/ghc/ghc/-/wikis/exceptions/precise-exceptions)
+-- for a more technical introduction to how GHC optimises around precise vs.
+-- imprecise exceptions.
+--
throwIO :: Exception e => e -> IO a
throwIO e = IO (raiseIO# (toException e))