summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2022-02-24 17:59:12 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-02-25 21:15:59 -0500
commit75e4e09040862dd12e6960d366868ca8ec434035 (patch)
tree333cbe280de2aa119ecb5c2011ebfa6bdb8f964d /libraries
parent929c280f991ee80ccf4fc1f451aa4c8a19113268 (diff)
downloadhaskell-75e4e09040862dd12e6960d366868ca8ec434035.tar.gz
base: Improve documentation of `throwIO` (#19854)
Now it takes a better account of precise vs. imprecise exception semantics. Fixes #19854.
Diffstat (limited to 'libraries')
-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))