{-# LANGUAGE BangPatterns #-} module Main where import qualified Data.ByteString as S import Data.IORef import Control.Monad makeBs :: Int -> S.ByteString makeBs n = S.replicate n (fromIntegral n) doStuff :: IORef [S.ByteString] -> Int -> IO () doStuff ref n = do let !bs = makeBs n modifyIORef ref (bs:) {-# NOINLINE doStuff #-} undo :: IORef [S.ByteString] -> IO () undo ref = do h <- atomicModifyIORef ref (\(x:xs) -> (xs,x)) S.length h `seq` return () main = do ref <- newIORef [S.empty] let fn n = do doStuff ref n when (rem 5 n /= 0 ) $ undo ref mapM_ fn (take 5000000 $ cycle [1..100]) var <- readIORef ref print $ length var