7.8. Bang patterns
Prev | Chapter 7. GHC Language Features | Next

## 7.8. Bang patterns

GHC supports an extension of pattern matching called bang patterns. Bang patterns are under consideration for Haskell Prime. The Haskell prime feature description contains more discussion and examples than the material below.

Bang patterns are enabled by the flag `-fbang-patterns`.

### 7.8.1. Informal description of bang patterns

The main idea is to add a single new production to the syntax of patterns:

      pat ::= !pat

Matching an expression `e` against a pattern `!p` is done by first evaluating `e` (to WHNF) and then matching the result against `p`. Example:

    f1 !x = True

This definition makes `f1` is strict in `x`, whereas without the bang it would be lazy. Bang patterns can be nested of course:

    f2 (!x, y) = [x,y]

Here, `f2` is strict in `x` but not in `y`. A bang only really has an effect if it precedes a variable or wild-card pattern:

    f3 !(x,y) = [x,y]
    f4 (x,y)  = [x,y]

Here, `f3` and `f4` are identical; putting a bang before a pattern that forces evaluation anyway does nothing.

Bang patterns work in `case` expressions too, of course:

    g5 x = let y = f x in body
    g6 x = case f x of { y -> body }
    g7 x = case f x of { !y -> body }

The functions `g5` and `g6` mean exactly the same thing. But `g7` evalutes `(f x)`, binds `y` to the result, and then evaluates `body`.

Bang patterns work in `let` and `where` definitions too. For example:

    let ![x,y] = e in b

is a strict pattern: operationally, it evaluates `e`, matches it against the pattern `[x,y]`, and then evaluates `b` The "`!`" should not be regarded as part of the pattern; after all, in a function argument `![x,y]` means the same as `[x,y]`. Rather, the "`!`" is part of the syntax of `let` bindings.

### 7.8.2. Syntax and semantics

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

      pat ::= !pat

There is one problem with syntactic ambiguity. Consider:

    f !x = 3

Is this a definition of the infix function "`(!)`", or of the "`f`" with a bang pattern? GHC resolves this ambiguity in favour of the latter. If you want to define `(!)` with bang-patterns enabled, you have to do so using prefix notation:

    (!) f x = 3

The semantics of Haskell pattern matching is described in Section 3.17.2 of the Haskell Report. To this description add one extra item 10, saying:

- Matching the pattern `!pat` against a value `v` behaves as follows:

  - if `v` is bottom, the match diverges

  - otherwise, `pat` is matched against `v`

Similarly, in Figure 4 of Section 3.17.3, add a new case (t):

    case v of { !pat -> e; _ -> e' }
       = v `seq` case v of { pat -> e; _ -> e' }

That leaves let expressions, whose translation is given in Section 3.12 of the Haskell Report. In the translation box, first apply the following transformation: for each pattern `pi` that is of form `!qi = ei`, transform it to `(xi,!qi) = ((),ei)`, and and replace `e0` by `(xi `seq` e0)`. Then, when none of the left-hand-side patterns have a bang at the top, apply the rules in the existing box.

The effect of the let rule is to force complete matching of the pattern `qi` before evaluation of the body is begun. The bang is retained in the translated form in case `qi` is a variable, thus:

      let !y = f x in b

The let-binding can be recursive. However, it is much more common for the let-binding to be non-recursive, in which case the following law holds: `(let !p = rhs in body)` is equivalent to `(case rhs of !p -> body)`

A pattern with a bang at the outermost level is not allowed at the top level of a module.

Prev | Up | Next
7.7. Arrow notation | Home | 7.9. Assertions