Haskell
Laziness and Strictness
Understand lazy evaluation and when to be strict.
By EZ4Code Team
lazystrictperformance
Code
-- Lazy: undefined doesn't crash if not used
const42 :: a -> Int
const42 _ = 42
print (const42 undefined) -- 42 (never evaluates undefined)
-- Infinite structures
primes = sieve [2..]
where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
take 5 primes -- [2,3,5,7,11]
-- Laziness can cause space leaks
sumTo :: Int -> Int
sumTo n = go n 0
where go 0 acc = acc
go k acc = go (k-1) (acc + k)
-- Builds a thunk: ((((0+1)+2)+3)...) — use bang patterns
sumTo' :: Int -> Int
sumTo' n = go n 0
where go 0 acc = acc
go k acc = let !acc' = acc + k in go (k-1) acc'
-- Forces acc' evaluation each step
-- seq and strict data fields
data StrictPair = StrictPair { _x :: !Int, _y :: !Int }
-- foldl' (strict) vs foldl (lazy)
import Data.List (foldl')
sumOk = foldl' (+) 0 [1..1000000] -- works
sumBad = foldl (+) 0 [1..1000000] -- space leakExplanation
Haskell is non-strict — values are computed only when needed. This enables infinite structures and composability, but can cause space leaks (thunks accumulate). Solutions: bang patterns (!) force evaluation, seq forces a value, foldl' is strict. Strict data fields (!) prevent thunk buildup. Use strictness annotations for accumulators in recursive loops.
More Haskell Snippets
Types and Type Classes
Define algebraic data types and type classes.
Maybe and IO Monads
Use Maybe for safety and IO for side effects.
List Comprehensions and Laziness
Generate lists with comprehensions and leverage laziness.
Functors, Applicatives, Monad Type Classes
The three core abstraction type classes.
IO and do Notation
Side-effectful programming in Haskell.
Modules and Imports
Organize code with modules and control exports.