
#13080: Memory leak caused by nested monadic loops -------------------------------------+------------------------------------- Reporter: Feuerbach | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Suppose it had been {{{ worker :: (Monad m) => m () worker = forever $ poll 1 poll :: (Monad m) => Int -> m a poll n | n>10000 = return () | otherwise = do print (expensive n) poll (n+1) }}} where `expensive` is expensive to compute. After printing out the results of 10000 calls to `expensive`, the `forever` will do it all again. Question: would you expect all the calls to `expensive` to be recomputed? Presumably not. `poll` builds a big action {{{ print (expensive 0) >> print (expensive 1) >> print (expensive 2) >> ... }}} and `forever` just repeatedly executes that action. But to remember all those results clearly takes O(n) space. Now in this case there is no real work to be shared, but that's clearly harder for GHC to spot. Especially when (as in this case) the monad is unspecified, so perhaps the call `return ()` does a tremendous amount of work. I'm not saying things can't be improved here, but you are in delicate territory. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13080#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler