seq :: a -> b -> b

evaluate



evaluate (seq a b) = do

a' b' return b'



evaluate

b

evaluate

id



evaluate (id a) = do

a' return a'



id

evaluate (id x)

evaluate x

id

evaluate

seq



evaluate (seq a a) = do

a' return a'



a

a

seq a a

a

a `seq` a

seq

id $! x

($!)



f $! x = x `seq` f x



id $! x

x `seq` id x

id x

x

x

seq

x `seq` x

id $! x

Haskell has one primitive construct for enforcing strictness,. The idea is that the first argument is evaluated to weak-head normal form (WHNF), then the second argument is evaluated to WHNF and returned. WHNF is reduction until the outermost bit is available - either a function value, or an outer constructor.You can model the behaviour by introducing anfunction, in a lower-level language, and showing how to perform reduction:Thefunction must return an evaluated argument, and it wants to returnwhich is not already evaluated, so it must make a recursive call. Thefunction for, which simply returns its argument, is:Notice that even thoughdoes "nothing", it still has to evaluate its argument. Of course,is the same as, soperforms no additional work.Haskell is lazy, so if an expression has already been evaluated, then thecall will be incredibly cheap, and just return the previous result. So let's consider the result of callingwith the same argument twice.This time the second evaluation ofis skipped, asis already evaluated. We can easily see that evaluation ofis exactly equivalent to. This means that any code which writesis. There is plenty of this code around, and one example (which prompted me to write this) is on slide 15 of this talk The other classicrelated mistake is. Theoperator is for strict application, and is defined:For the particular instance of, we obtain. Of course, all thatdoes is evaluate, so again there is no change from just writingThere are valid uses of, but any time you see either of the following constructs, youthe programmer got it wrong: