Annotating strictness and unpacking datatype fields
Recall that in the previous chapter, we used seq to force strict evaluation. With the BangPatterns extension, we can force functions arguments. Strict arguments are evaluated WHNF just before entering the function body:
{-# LANGUAGE BangPatterns #-}
f !s (x:xs) = f (s + 1) xs
f !s _ = sUsing bangs for annotating strictness in fact predates the BangPatterns extension (and the older compiler flag -fbang-patterns in GHC 6.x). With just plain Haskell98, we are allowed to use bangs to make datatype fields strict:
> data T = T !Int
A bang in front of a field ensures that whenever the outer constructor (T above) is in WHNF, the inner field is as well in WHNF. We can check this:
> T undefined `seq` () *** Exception: Prelude.undefined
There are no restrictions to which fields can be strict, be it recursive or polymorphic fields, although it rarely makes sense to make recursive fields strict. Consider the fully strict linked list:
data List...