Consider the following program: module A where import Control.Monad.State f :: StateT Int IO () f = (sequence_ $ repeat $ return ()) t = runStateT f 0 When t is evaluated under ghci or hugs, the program quickly runs out of heap memory. What's going on here? Is this inherent in StateT monad? If so, then this is very surprising, I would expect f to run in constant space for any sensible monad. Wojtek
wojtek:
Consider the following program:
module A where
import Control.Monad.State
f :: StateT Int IO () f = (sequence_ $ repeat $ return ())
t = runStateT f 0
When t is evaluated under ghci or hugs, the program quickly runs out of heap memory. What's going on here? Is this inherent in StateT monad? If so, then this is very surprising, I would expect f to run in constant space for any sensible monad.
For any sensible compiler... I replaced 't' with 'main', and commented out the 'module' line. I then compiled this program under GHC 6.0.1 or 6.3 on 4 different architectures (x86, ia64, mips64, sparc) and it doesn't run out of heap, at least not in the time I was giving it, with and without optimisations, and via the NCG where applicable. GHCi (on the machines that support it : x86, ia64, sparc), didn't result in heap trouble either. What version of GHC are you using? And how long was "quickly"? Cheers, Don
On Thu, Nov 13, 2003 at 05:19:28PM -0500, Wojtek Moczydlowski wrote:
Consider the following program:
module A where
import Control.Monad.State
f :: StateT Int IO () f = (sequence_ $ repeat $ return ())
t = runStateT f 0
When t is evaluated under ghci or hugs, the program quickly runs out of heap memory. What's going on here? Is this inherent in StateT monad? If so, then this is very surprising, I would expect f to run in constant space for any sensible monad.
There is more to it. Let's define t2 :: IO () t2 = sequence_ $ repeat $ return () t2 behaves in the same way. However, if you compile the module with GHC with optimisations turned on, both t and t2 run in constant space. OK, I understand that GHC doesn't do optimisations in interpreted code. The strange thing is that if you execute *A> runStateT (sequence_ $ repeat $ return ()) 1 :: IO ((), Int) or *A> (sequence_ $ repeat $ return ()) :: IO () directly in GHCi, then is seems to run in constant space.
Wojtek
Best regards, Tom -- .signature: Too many levels of symbolic links
On Fri, Nov 14, 2003 at 12:22:00AM +0100, Tomasz Zielonka wrote:
There is more to it. Let's define
t2 :: IO () t2 = sequence_ $ repeat $ return ()
t2 behaves in the same way. However, if you compile the module with GHC with optimisations turned on, both t and t2 run in constant space. OK, I understand that GHC doesn't do optimisations in interpreted code.
The strange thing is that if you execute
*A> runStateT (sequence_ $ repeat $ return ()) 1 :: IO ((), Int)
directly in GHCi, then is seems to run in constant space.
I guess it is an infamous CAF leak - f expands into an infinite expression which can't be reclaimed because it is bound to a top-level variable. When compiling with optimisations GHC somehow manages to avoid this problem. Can somebody confirm this? Best regards, Tom -- .signature: Too many levels of symbolic links
participants (3)
-
dons@cse.unsw.edu.au -
Tomasz Zielonka -
Wojtek Moczydlowski