
I have a space leak in a function that increments a number inside IORef or STRef (either lazy or strict). Is this the kind of problem that can be diagnosed and fixed using the approach described in RWH, with space profiling? Otherwise what's the right approach to diagnose and fix? I wrote a non-list-using, and tail call-using, iterateMonadic funcation that does the same thing as replicateM, in case the problem was due to iterateM using a list structure, but iterateMonadic and replicateM had same memory leak. I can run this problem with +RTS -K100M -RTS but this aditional memory shouldn't be needed. {-# LANGUAGE RankNTypes, BangPatterns #-} import Data.List import Control.Monad.State.Strict import Data.Array.MArray import Data.Array.IO import Data.Array.ST import Control.Monad.ST import Control.Applicative import Data.IORef import Data.STRef.Strict import Data.STRef import GHC.ST import Control.Applicative ((<$>)) main = do -- putStrLn "ioIters, iterateMonadic: " -- print =<< ioIters iters iterateMonadic -- putStrLn "ioIters, replicateM_: " -- print =<< ioIters iters replicateM_ -- putStrLn "lazySTIters, iterateMonadic: " -- print $ lazySTIters iters iterateMonadic -- putStrLn "lazySTIters, replicateM_: " -- print $ lazySTIters iters replicateM_ putStrLn "strictSTIters, iterateMonadic: " print $ strictSTIters iters iterateMonadic -- putStrLn "strictSTIters, replicateM_: " -- print $ strictSTIters iters replicateM_ type Iter = (Monad m) => Int -> m () -> m () iterateMonadic :: (Monad m) => Int -> m a -> m a iterateMonadic n mx = do let loop 0 acc = acc loop n acc = loop (n-1) (acc >> mx ) loop n mx iters = 10^7 ioIters :: Int -> Iter -> IO Int ioIters numIters iteratorM = do tmp <- newIORef 0 iteratorM numIters ( modifyIORef tmp (+1) ) readIORef tmp lazySTIters :: Int -> Iter -> Int lazySTIters numIters iteratorM = runST $ do tmp <- Data.STRef.newSTRef 0 iteratorM numIters ( Data.STRef.modifySTRef tmp (+1) ) Data.STRef.readSTRef tmp strictSTIters :: Int -> Iter -> Int strictSTIters numIters iteratorM = runST $ do tmp <- Data.STRef.Strict.newSTRef 0 iteratorM numIters ( Data.STRef.Strict.modifySTRef tmp incr' ) Data.STRef.Strict.readSTRef tmp incr' (!x) = x + 1