Docs: clarify the interaction between throwSTM and catchSTM.
authorIan Denhardt <ian@zenhack.net>
Fri, 26 Oct 2018 22:05:05 +0000 (18:05 -0400)
committerBen Gamari <ben@smart-cactus.org>
Mon, 29 Oct 2018 19:11:47 +0000 (15:11 -0400)
The previous doc comments were not terribly clear on what was or wasn't
rolled back when an exception was caught in STM. This misunderstanding
was the source of a bug in another project of mine, and folks on
`#haskell` found it confusing as well.

libraries/base/GHC/Conc/Sync.hs

index 6751de7..7038b0d 100644 (file)
@@ -752,7 +752,12 @@ orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
 -- | A variant of 'throw' that can only be used within the 'STM' monad.
 --
 -- Throwing an exception in @STM@ aborts the transaction and propagates the
--- exception.
+-- exception. If the exception is caught via 'catchSTM', only the changes
+-- enclosed by the catch are rolled back; changes made outside of 'catchSTM'
+-- persist.
+--
+-- If the exception is not caught inside of the 'STM', it is re-thrown by
+-- 'atomically', and the entire 'STM' is rolled back.
 --
 -- Although 'throwSTM' has a type that is an instance of the type of 'throw', the
 -- two functions are subtly different:
@@ -770,7 +775,12 @@ orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
 throwSTM :: Exception e => e -> STM a
 throwSTM e = STM $ raiseIO# (toException e)
 
--- |Exception handling within STM actions.
+-- | Exception handling within STM actions.
+--
+-- @'catchSTM' m f@ catches any exception thrown by @m@ using 'throwSTM',
+-- using the function @f@ to handle the exception. If an exception is
+-- thrown, any changes made by @m@ are rolled back, but changes prior to
+-- @m@ persist.
 catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a
 catchSTM (STM m) handler = STM $ catchSTM# m handler'
     where