Haskell Seq and Strictness
Seq and strictness are Haskell's way of forcing a value to be computed now instead of later. They control when work happens, not what the answer is.
Seq returns the second value
Seq evaluates the sum and then gives the word. The printed word proves seq kept the second value.
main :: IO ()
main = putStrLn ((2 + 3) `seq` "forced")Strict application evaluates its argument first
The argument is a product. Strict application evaluates it before adding 10.
main :: IO ()
main = print ((+ 10) $! (3 * 4))A forced division by zero can be caught
Seq forces the division by zero inside evaluate. Catch turns the ArithException into a printed word.
import Control.Exception (ArithException, catch, evaluate)
handler :: ArithException -> IO String
handler _ = return "caught"
main :: IO ()
main = do
outcome <- catch (evaluate (let bad = 1 `div` 0 in bad `seq` "done") >> return "no-error") handler
putStrLn outcomeExample
main :: IO ()
main = do
let total = 6 * 7
print (total `seq` total)
print ((+ 1) $! total)Key points
- Seq: x `seq` y evaluates x and then gives y.
- Strict application: f $! x evaluates x before f runs.
- Order: strictness controls when work happens, not what the answer is.
- Forced failure: forcing a division by zero raises ArithException.
- Catching: evaluate and catch can turn a forced failure into a printed result.
In this example, total is 42. The first print uses seq to force total and then prints it. The second print uses strict application to force total before adding 1.
Note
Haskell is lazy by default, so strictness is added only where timing matters.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What does x `seq` y do?