content: {-# LANGUAGE Trustworthy #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  Data.STRef
  -- Copyright   :  (c) The University of Glasgow 2001
  -- License     :  BSD-style (see the file libraries/base/LICENSE)
  --
  -- Maintainer  :  libraries@haskell.org
  -- Stability   :  experimental
  -- Portability :  non-portable (uses Control.Monad.ST)
  --
  -- Mutable references in the (strict) ST monad.
  --
  -----------------------------------------------------------------------------
  
  module Data.STRef (
          -- * STRefs
          STRef,          -- abstract
          newSTRef,
          readSTRef,
          writeSTRef,
          modifySTRef,
          modifySTRef'
   ) where
  
  import GHC.ST
  import GHC.STRef
  
  -- | Mutate the contents of an 'STRef'.
  --
  -- >>> :{
  -- runST (do
  --     ref <- newSTRef ""
  --     modifySTRef ref (const "world")
  --     modifySTRef ref (++ "!")
  --     modifySTRef ref ("Hello, " ++)
  --     readSTRef ref )
  -- :}
  -- "Hello, world!"
  --
  -- Be warned that 'modifySTRef' does not apply the function strictly.  This
  -- means if the program calls 'modifySTRef' many times, but seldomly uses the
  -- value, thunks will pile up in memory resulting in a space leak.  This is a
  -- common mistake made when using an STRef as a counter.  For example, the
  -- following will leak memory and may produce a stack overflow:
  --
  -- >>> import Control.Monad (replicateM_)
  -- >>> :{
  -- print (runST (do
  --     ref <- newSTRef 0
  --     replicateM_ 1000 $ modifySTRef ref (+1)
  --     readSTRef ref ))
  -- :}
  -- 1000
  --
  -- To avoid this problem, use 'modifySTRef'' instead.
  modifySTRef :: STRef s a -> (a -> a) -> ST s ()
  modifySTRef ref f = writeSTRef ref . f =<< readSTRef ref
  
  -- | Strict version of 'modifySTRef'
  --
  -- @since 4.6.0.0
  modifySTRef' :: STRef s a -> (a -> a) -> ST s ()
  modifySTRef' ref f = do
      x <- readSTRef ref
      let x' = f x
      x' `seq` writeSTRef ref x'
  