
Don Stewart schrieb:
dvde:
Don Stewart schrieb:
It is not possible to write a modifyIORef that *doesn't* leak memory!
Why? Or can one read about it somewhere?
Try writing a version of this program, using modifyIORef only, such that it doesn't exhaust the heap:
import Data.IORef import Control.Monad import System.IO.Unsafe
ref :: IORef Int ref = unsafePerformIO $ newIORef 0 {-# NOINLINE ref #-}
main = do modifyIORef ref (\a -> a + 1) main
Run it in a constrained environment, so you don't thrash:
$ ./A +RTS -M100M Heap exhausted; Current maximum heap size is 99999744 bytes (95 MB); use `+RTS -M<size>' to increase it.
The goal is to run in constant space.
-- Don
Hm, do you say it is not possible to write a modifyIORef function that does not leak memory, or do you say it is not possible to use the (existing) modifyIORef without having memory leaks? I wrote the following which runs in constant space, but it introduces strictness, which is not always desirable. And yes, using only modifyIORef this could not be done this way, because the strict evaluation happens on the IO-Monad-level. But such examples occured already in this thread. import Data.IORef import Control.Monad import System.IO.Unsafe ref :: IORef Int ref = unsafePerformIO $ newIORef 0 {-# NOINLINE ref #-} main = do myModifyIORef ref (\a -> a + 1) main myModifyIORef :: IORef a -> (a->a) -> IO () myModifyIORef ref f = do a <- readIORef ref let a' = f a seq a' $ writeIORef ref a' So would it make sense to create a strict modifyIORef' function? best regards, daniel