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 _ = s
Using 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...