Question about BangPatterns semantics/documentation

Herbert Valerio Riedel hvriedel at gmail.com
Sun Aug 3 09:31:30 UTC 2014



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


More information about the ghc-devs mailing list