Ticket #7058: 0001-Add-strict-version-of-modifySTRef.patch

File 0001-Add-strict-version-of-modifySTRef.patch, 1.9 KB (added by joeyadams, 3 years ago)
  • Data/STRef.hs

    From 9bb88d6a5bf9188f468bfe67eb1877eefa478927 Mon Sep 17 00:00:00 2001
    From: Joey Adams <[email protected]>
    Date: Sat, 7 Jul 2012 22:13:52 -0400
    Subject: [PATCH] Add strict version of modifySTRef
    
    Also, add a warning to modifySTRef, mostly copy-pasted from the warning
    for modifyIORef.
    ---
     Data/STRef.hs |   24 ++++++++++++++++++++++--
     1 files changed, 22 insertions(+), 2 deletions(-)
    
    diff --git a/Data/STRef.hs b/Data/STRef.hs
    index c628bb6..7c884e5 100644
    a b module Data.STRef ( 
    2121        newSTRef,       -- :: a -> ST s (STRef s a)
    2222        readSTRef,      -- :: STRef s a -> ST s a
    2323        writeSTRef,     -- :: STRef s a -> a -> ST s ()
    24         modifySTRef     -- :: STRef s a -> (a -> a) -> ST s ()
     24        modifySTRef,    -- :: STRef s a -> (a -> a) -> ST s ()
     25        modifySTRef'    -- :: STRef s a -> (a -> a) -> ST s ()
    2526 ) where
    2627
    2728import Prelude
    import Data.Typeable 
    3940INSTANCE_TYPEABLE2(STRef,stRefTc,"STRef")
    4041#endif
    4142
    42 -- |Mutate the contents of an 'STRef'
     43-- | Mutate the contents of an 'STRef'.
     44--
     45-- Be warned that 'modifySTRef' does not apply the function strictly.  This
     46-- means if the program calls 'modifySTRef' many times, but seldomly uses the
     47-- value, thunks will pile up in memory resulting in a space leak.  This is a
     48-- common mistake made when using an STRef as a counter.  For example, the
     49-- following will leak memory and likely produce a stack overflow:
     50--
     51-- >print $ runST $ do
     52-- >    ref <- newSTRef 0
     53-- >    replicateM_ 1000000 $ modifySTRef ref (+1)
     54-- >    readSTRef ref
     55--
     56-- To avoid this problem, use 'modifySTRef'' instead.
    4357modifySTRef :: STRef s a -> (a -> a) -> ST s ()
    4458modifySTRef ref f = writeSTRef ref . f =<< readSTRef ref
    4559
     60-- | Strict version of 'modifySTRef'
     61modifySTRef' :: STRef s a -> (a -> a) -> ST s ()
     62modifySTRef' ref f = do
     63    x <- readSTRef ref
     64    let x' = f x
     65    x' `seq` writeSTRef ref x'