If you're out of luck, your first infinite list will use an infinite amount of memory. So use your second infinite list (or, if you prefer an anonymous infinite list, use repeat from Prelude).
Demonstration. Perhaps run watch free -m in another window by doing this.
$ cat so.hs import Control.Exception (evaluate) import System.IO (hFlush, stdout) with :: String -> [Int] -> IO () with s xs = do putStrLn $ "Summing part of a " ++ s theSum <- evaluate $ sum (take 100000000 xs) firstElem <- evaluate $ head xs putStrLn $ "sum $ take 100000000 [" ++ show firstElem ++ "...] is " ++ show theSum main :: IO () main = do with "call to repeat" (repeat 1) putStr "Press return to continue..." hFlush stdout getLine with "list comprehension" [1,1..] $ ghc -O
The first summation is performed in constant space. The second summation consumes memory, so I interrupt it before it forces my laptop to swap.
In this simple case, we could avoid a space leak by calculating firstElem before calculating theSum , but in the real world this may not be possible, or at least difficult to track. It is better to avoid this using repeat .
(Optimization note: if we do not pass the -O flag to ghc , then sum will leak into space during both summations. It is difficult to rewrite sum = foldl' (+) 0 so that it does not leak even without -O . I donβt know which considerations lead to the current implementation instead.)
source share