Skip to content

Float out causes major space leak

This issue originally was on haskell-cafe https://mail.haskell.org/pipermail/haskell-cafe/2015-June/120113.html

The following code has a space leak

numbers = [1..200]

replicateM' :: Monad m => Int -> m a -> m [a]
replicateM' 0 xs = return []
replicateM' n xs = do
  a <- xs
  b <- replicateM' (n-1) xs
  return (a:b)

test :: [[Int]]
test = replicateM' 4 numbers

main = print test

The recursive call in replicateM' gets floated out. This then causes a very large (200^3^ elements) list to be kept in memory instead of being lazily produced and consumed each time.

A similar thing happens to the replicateM in Control.Monad but it is harder to spot as a lot of specialisation and fusion goes on before the float-out happens

This is similar to #7367 but in this case we have a huge space-leak instead of just adding allocations.

Edited by AlexET
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information