🎓 A1Learner
🔍
0 of 50 lessons completed

Haskell Lazy Evaluation

Lazy evaluation is Haskell's way of waiting until a value is really needed before computing it. It lets a program define values it may never use.

An unused value is never computed

The program defines a division by zero but never uses it. Only the safe message is printed.

main :: IO ()
main = let bad = 1 `div` 0 in putStrLn "lazy-ok"

Only the needed part is computed

The pair holds a safe number and a division by zero. Printing only the first part leaves the second part untouched.

main :: IO ()
main = print (fst (42, 1 `div` 0))

A value is computed when it is printed

The sum is only a promise until print asks for it. Printing it gives the computed result.

main :: IO ()
main = let total = 2 + 3 in print total

Example

main :: IO ()
main = do
  let xs = [1 + 1, 2 + 2, 3 + 3]
  print (head xs)
  print (xs !! 2)

Key points

  • Thunk: a value that is promised but not yet computed.
  • Forcing: the moment a program actually needs a thunk's value.
  • Unused values: a thunk that is never forced is never computed.
  • Printing: printing a value forces the parts of it that are shown.
  • Infinite data: laziness makes endless lists usable when only a part is taken.

In this example, xs holds three promised sums. The first print asks only for the head, so it shows 2. The second print asks for the element at index 2, so it shows 6.

Note

laziness is the default in Haskell, so strictness must be asked for on purpose.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

What does lazy evaluation mean?