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

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

    From 9bb88d6a5bf9188f468bfe67eb1877eefa478927 Mon Sep 17 00:00:00 2001
    From: Joey Adams <joeyadams3.14159@gmail.com>
    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'