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 totalExample
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?