From: simonpj@microsoft.com Date: Mon, 4 Sep 2006 12:34:38 +0000 (+0000) Subject: Documentation for bang patterns, and other improvements X-Git-Tag: Before_FC_branch_merge~79 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=6da4233da131954bbc1d9922104d7bd01edc5c56 Documentation for bang patterns, and other improvements --- diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml index f69fc45..6b348fe 100644 --- a/docs/users_guide/flags.xml +++ b/docs/users_guide/flags.xml @@ -545,45 +545,46 @@ - Enable overlapping instances + Enable overlapping instances dynamic - - Enable undecidable instances - dynamic - - - - Enable incoherent instances. + Enable incoherent instances. Implies dynamic - - Enable arrow notation extension + + Enable undecidable instances dynamic - + n - set the limit for context reduction + set the limit for context reduction dynamic + + Enable arrow + notation extension + dynamic + + + or - Enable foreign function interface (implied by + Enable foreign function interface (implied by ) dynamic - Enable generics + Enable generic classes dynamic @@ -595,7 +596,7 @@ - Enable Implicit Parameters. + Enable Implicit Parameters. Implied by . dynamic @@ -614,36 +615,42 @@ - Disable the monomorphism restriction + Disable the monomorphism restriction dynamic - Make pattern bindings polymorphic + Make pattern bindings polymorphic dynamic - Use GHCi's extended default rules in a normal module + Use GHCi's extended default rules in a normal module dynamic - Enable lexically-scoped type variables. + Enable lexically-scoped type variables. Implied by . dynamic - Enable Template Haskell. + Enable Template Haskell. No longer implied by . dynamic + + + Enable bang patterns. + dynamic + + diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index fd6e322..588dfef 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -116,39 +116,11 @@ documentation describes all the libraries that come with GHC. - : - - - - Switch off the Haskell 98 monomorphism restriction. - Independent of the - flag. - - - - - - : - - + ,: - As an experimental change, we are exploring the possibility of - making pattern bindings monomorphic; that is, not generalised at all. - A pattern binding is a binding whose LHS has no function arguments, - and is not a simple variable. For example: - - f x = x -- Not a pattern binding - f = \x -> x -- Not a pattern binding - f :: Int -> Int = \x -> x -- Not a pattern binding - - (g,h) = e -- A pattern binding - (f) = e -- A pattern binding - [x] = e -- A pattern binding - -Experimentally, GHC now makes pattern bindings monomorphic by -default. Use to recover the -standard behaviour. + These two flags control how generalisation is done in + See . @@ -4816,6 +4788,150 @@ Because the preprocessor targets Haskell (rather than Core), + + + +Bang patterns +<indexterm><primary>Bang patterns</primary></indexterm> + +GHC supports an extension of pattern matching called bang +patterns. Bang patterns are under consideration for Haskell Prime. +The the +Haskell prime feature description contains more discussion and examples +than the material below. + + +Bang patterns are enabled by the flag . + + + +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. + + + + + +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 inf 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. + + + + @@ -6415,6 +6531,51 @@ Just to finish with, here's another example I rather like: + +Control over monomorphism + +GHC supports two flags that control the way in which generalisation is +carried out at let and where bindings. + + + +Switching off the dreaded Monomorphism Restriction + + +Haskell's monomorphism restriction (see +Section +4.5.5 +of the Haskell Report) +can be completely switched off by +. + + + + +Monomorphic patteern bindings + + + + As an experimental change, we are exploring the possibility of + making pattern bindings monomorphic; that is, not generalised at all. + A pattern binding is a binding whose LHS has no function arguments, + and is not a simple variable. For example: + + f x = x -- Not a pattern binding + f = \x -> x -- Not a pattern binding + f :: Int -> Int = \x -> x -- Not a pattern binding + + (g,h) = e -- A pattern binding + (f) = e -- A pattern binding + [x] = e -- A pattern binding + +Experimentally, GHC now makes pattern bindings monomorphic by +default. Use to recover the +standard behaviour. + + + +