!
as enabled by the BangPatterns
extension is always in a pattern, before a binding, like this:
add :: Int -> Int -> Int
add !a b = a + b
It means "if execution tries to force this pattern case, then reduce the !-ed binding to weak head normal form before evaluating the right hand side of the pattern"
f $! x
means "if execution tries to force this "f $! x" expression, then proceed by first reducing "x" to weak head normal form, then applying "f" to the reduced "x" ".
In both cases, note that the strictness annotations only express a conditional statement. If I have a f $! x
lying around (where x
might be a thunk for a complicated computation), if the execution never tries to force f $! x
, then of course nothing of it will be evaluated.