🎓 A1Learner
🔍
0 of 47 lessons completed

Haskell Memory Patterns

A memory pattern is the shape of how a program holds values while it works. A lazy list held whole is a space leak, while a consumed stream or a strict fold keeps memory small.

Take consumes only the head of a list

Only the first hundred numbers are taken. The sum and the count describe just that head.

main :: IO ()
main = do
  print (sum (take 100 [1..]))
  print (length (take 100 [1..]))

A strict fold summarises without holding thunks

The strict fold adds as it goes. The length confirms the whole list was covered.

import Data.List (foldl')
main :: IO ()
main = do
  print (foldl' (+) 0 [1..100])
  print (length [1..100])

Chunks add up to the whole total

The list is summed in two chunks. The two chunk sums add to the total of the whole list.

main :: IO ()
main = do
  let xs = [1..20]
  print (sum (take 10 xs))
  print (sum (drop 10 xs))
  print (sum xs)

Example

import Data.List (foldl')
main :: IO ()
main = do
  let ws = ["red", "green", "blue", "gold"]
  print (length ws)
  print (foldl' (+) 0 (map length ws))

Key points

  • Space leak: memory held by values a program no longer needs.
  • Consumed stream: a list processed piece by piece and then let go.
  • Strict fold: a fold that forces its accumulator so no chain of thunks builds up.
  • Use take to work with only the head of a long or endless list.
  • Use a strict fold when only a summary of a list is needed.

In this example, the program lists four words, prints how many there are, then folds over their lengths with a strict fold and prints the total number of letters.

Note

this lesson proves its claims with counts and sums, never with a memory measurement.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

What shape should a program prefer when it only needs a summary of a long list?