11

From GHC user guide it seems like most Pat can be PBangPat, but there are a few exceptions. e.g. top-level bangs in a module (like !main) aren't allowed and x : !xs fails to parse x : (!xs) parses thanks @chi. What is the formal specification about where the bangs can be added? I've looked into some chapters of the user guide and the Report but found nothing.

rem
  • 893
  • 4
  • 18

1 Answers1

6

There is no accepted formal specification for BangPatterns since they are not a part of any Haskell Report. The closest thing we have to a specification is the User's Guide along with the haskell-prime proposal it links to.

Both of those sources explicitly mention that a bang pattern is not allowed at the top level of a module.

As for x : !xs, the User's Guide has this to say about the syntax of bang patterns:

We add a single new production to the syntax of patterns:

pat  ::= !pat

It should be read in conjunction with the Haskell 2010 Report:

pat  ::= lpat qconop pat
       | lpat

lpat ::= apat
       | - (integer | float)
       | gcon apat_1 ... apat_k

apat ::= var [ @ apat]
       | ...
       | ( pat )
       | ...

According to these rules x : !xs actually should parse (since !xs is a pat, the whole thing is lpat qconop pat). So either the User's Guide (and the haskell-prime proposal) is wrong or GHC is wrong on this point.

I believe that in practice the syntax accepted by GHC is "anything that looks like a valid expression" including interpreting (!x) as a section of the operator !. For example (! Just x) is accepted as a pattern but (! ! x) is not.

Reid Barton
  • 14,951
  • 3
  • 39
  • 49
  • 2
    Actually [the relevant section of the User's Guide](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bang-patterns.html#bang-patterns-sem) is so old that it links to the *Haskell 98* report, and the BNF grammar at that time treated precedence differently. [For patterns in particular](https://www.haskell.org/onlinereport/exps.html#sect3.17.1), adding `pat ::= !pat` means to add it at the *lowest precedence*. – Ørjan Johansen Aug 04 '15 at 03:08
  • Although disturbingly, by this reading `(! ! x)` *should* work but doesn't. – Ørjan Johansen Aug 04 '15 at 03:14
  • @ØrjanJohansen, oh good point. I didn't try following the links to the Report since I already had the 2010 Report open in another tab. That does make the description closer to reality, though as you say still not quite the same. – Reid Barton Aug 04 '15 at 15:11
  • See also https://ghc.haskell.org/trac/ghc/ticket/1087 and https://ghc.haskell.org/trac/ghc/ticket/10732. – thomie Dec 13 '15 at 23:03