Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell does not garbage collect the head of a list?

Consider the following program:

module Main where

import Control.Monad.List

main = runListT $ do
  x <- ListT $ return $ [0..1000000000]
  lift $ print x

Ideally, we would want the list to be garbage collected as we consume it, so that this program only uses constant memory. But when I compile and run it with

ghc Main.hs -O2 -o Main

I see that it keep using more and more memory. How do I convince Haskell to GC the consumed elements of the list?

like image 334
yong Avatar asked Nov 23 '14 23:11

yong


People also ask

Is Haskell garbage collected?

The Haskell runtime system employs a generational garbage collector (GC) with two generations 2. Generations are numbered starting with the youngest generation at zero. Values are always allocated in a special part of the youngest generation called the nursery.

Why do functional languages need garbage collectors?

The fundamental challenge garbage collection addresses is freeing memory that is not, or is not known to be, used in a stack-like fashion. It is most especially useful when there is no clear place in the source code that can be pinpointed as the end of the object's lifetime.


1 Answers

The ListT in transformers doesn't stream or run in constant space. The ListT in pipes does!

import Control.Monad (mzero)
import Pipes

main = runListT (do
    x <- Select (each [0..1000000000])
    lift (print x)
    mzero )

I also just uploaded pipes-4.1.4 today, which relaxes runListT to not require the mzero at the end, so then it would just be:

-- Requires `pipes-4.1.4`
import Pipes

main = runListT (do
    x <- Select (each [0..1000000000])
    lift (print x) )
like image 147
Gabriella Gonzalez Avatar answered Oct 28 '22 23:10

Gabriella Gonzalez