
The GHC User's Guide[1] says: | There is one (apparent) exception to this general rule that a bang | only makes a difference when it precedes a variable or wild-card: a | bang at the top level of a let or where binding makes the binding | strict, regardless of the pattern. (We say "apparent" exception | because the Right Way to think of it is that the bang at the top of a | binding is not part of the pattern; rather it is part of the syntax of | the binding, creating a "bang-pattern binding".) For example: | | let ![x,y] = e in b | | is a bang-pattern binding. Operationally, it behaves just like a case | expression: | | case e of [x,y] -> b However, the following two functions are not equivalent after compilation to Core: g, h :: (Int -> Int) -> Int -> () g f x = let !y = f x in () h f x = case f x of y -> () In fact, compilation results in g = \ (f_asi :: Int -> Int) (x_asj :: Int) -> case f_asi x_asj of _ [Occ=Dead] { I# ipv_sKS -> () } h = \ _ [Occ=Dead] _ [Occ=Dead] -> () Is the documentation inaccurate/incomplete/I-missed-something or is the implementation to blame? Cheers, hvr [1]: http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/bang-patterns.html