X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=7e78c7299c9a69de6afc5bc800e1e6bd85711f93;hp=da6a125eb4a6cf30872ec2ee74d608eb19e8b203;hb=6a05ec5ef5373f61b7f9f5bdc344483417fa801b;hpb=4d60ffc3e9a167c64e395046e1d2ef51eeb165ec diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index da6a125..7e78c72 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -710,6 +710,202 @@ qualifier list has just one element, a boolean expression. + + + +View patterns + + + +View patterns are enabled by the flag -XViewPatterns. +More information and examples of view patterns can be found on the +Wiki +page. + + + +View patterns are somewhat like pattern guards that can be nested inside +of other patterns. They are a convenient way of pattern-matching +against values of abstract types. For example, in a programming language +implementation, we might represent the syntax of the types of the +language as follows: + + +type Typ + +data TypView = Unit + | Arrow Typ Typ + +view :: Type -> TypeView + +-- additional operations for constructing Typ's ... + + +The representation of Typ is held abstract, permitting implementations +to use a fancy representation (e.g., hash-consing to managage sharing). + +Without view patterns, using this signature a little inconvenient: + +size :: Typ -> Integer +size t = case view t of + Unit -> 1 + Arrow t1 t2 -> size t1 + size t2 + + +It is necessary to iterate the case, rather than using an equational +function definition. And the situation is even worse when the matching +against t is buried deep inside another pattern. + + + +View patterns permit calling the view function inside the pattern and +matching against the result: + +size (view -> Unit) = 1 +size (view -> Arrow t1 t2) = size t1 + size t2 + + +That is, we add a new form of pattern, written +expression -> +pattern that means "apply the expression to +whatever we're trying to match against, and then match the result of +that application against the pattern". The expression can be any Haskell +expression of function type, and view patterns can be used wherever +patterns are used. + + + +The semantics of a pattern ( +exp -> +pat ) are as follows: + + + + Scoping: + +The variables bound by the view pattern are the variables bound by +pat. + + + +Any variables in exp are bound occurrences, +but variables bound "to the left" in a pattern are in scope. This +feature permits, for example, one argument to a function to be used in +the view of another argument. For example, the function +clunky from can be +written using view patterns as follows: + + +clunky env (lookup env -> Just val1) (lookup env -> Just val2) = val1 + val2 +...other equations for clunky... + + + + +More precisely, the scoping rules are: + + + +In a single pattern, variables bound by patterns to the left of a view +pattern expression are in scope. For example: + +example :: Maybe ((String -> Integer,Integer), String) -> Bool +example Just ((f,_), f -> 4) = True + + +Additionally, in function definitions, variables bound by matching earlier curried +arguments may be used in view pattern expressions in later arguments: + +example :: (String -> Integer) -> String -> Bool +example f (f -> 4) = True + +That is, the scoping is the same as it would be if the curried arguments +were collected into a tuple. + + + + + +In mutually recursive bindings, such as let, +where, or the top level, view patterns in one +declaration may not mention variables bound by other declarations. That +is, each declaration must be self-contained. For example, the following +program is not allowed: + +let {(x -> y) = e1 ; + (y -> x) = e2 } in x + + +(We may lift this +restriction in the future; the only cost is that type checking patterns +would get a little more complicated.) + + + + + + + + + + Typing: If exp has type +T1 -> +T2 and pat matches +a T2, then the whole view pattern matches a +T1. + + + Matching: To the equations in Section 3.17.3 of the +Haskell 98 +Report, add the following: + +case v of { (e -> p) -> e1 ; _ -> e2 } + = +case (e v) of { p -> e1 ; _ -> e2 } + +That is, to match a variable v against a pattern +( exp +-> pat +), evaluate ( +exp v +) and match the result against +pat. + + + Efficiency: When the same view function is applied in +multiple branches of a function definition or a case expression (e.g., +in size above), GHC makes an attempt to collect these +applications into a single nested case expression, so that the view +function is only applied once. Pattern compilation in GHC follows the +matrix algorithm described in Chapter 4 of The +Implementation of Functional Programming Languages. When the +top rows of the first column of a matrix are all view patterns with the +"same" expression, these patterns are transformed into a single nested +case. This includes, for example, adjacent view patterns that line up +in a tuple, as in + +f ((view -> A, p1), p2) = e1 +f ((view -> B, p3), p4) = e2 + + + + The current notion of when two view pattern expressions are "the +same" is very restricted: it is not even full syntactic equality. +However, it does include variables, literals, applications, and tuples; +e.g., two instances of view ("hi", "there") will be +collected. However, the current implementation does not compare up to +alpha-equivalence, so two instances of (x, view x -> +y) will not be coalesced. + + + + + + + + + @@ -863,10 +1059,11 @@ This name is not supported by GHC. + + Rebindable syntax - GHC allows most kinds of built-in syntax to be rebound by the user, to facilitate replacing the Prelude with a home-grown version, for example. @@ -1020,6 +1217,170 @@ This reduces the clutter of qualified names when you import two records from different modules that use the same field name. + + + + +Record puns + + + +Record puns are enabled by the flag -XRecordPuns. + + + +When using records, it is common to write a pattern that binds a +variable with the same name as a record field, such as: + + +data C = C {a :: Int} +f (C {a = a}) = a + + + + +Record punning permits the variable name to be elided, so one can simply +write + + +f (C {a}) = a + + +to mean the same pattern as above. That is, in a record pattern, the +pattern a expands into the pattern a = +a for the same name a. + + + +Note that puns and other patterns can be mixed in the same record: + +data C = C {a :: Int, b :: Int} +f (C {a, b = 4}) = a + +and that puns can be used wherever record patterns occur (e.g. in +let bindings or at the top-level). + + + +Record punning can also be used in an expression, writing, for example, + +let a = 1 in C {a} + +instead of + +let a = 1 in C {a = a} + + +Note that this expansion is purely syntactic, so the record pun +expression refers to the nearest enclosing variable that is spelled the +same as the field name. + + + + + + + +Record wildcards + + + +Record wildcards are enabled by the flag -XRecordWildCards. + + + +For records with many fields, it can be tiresome to write out each field +individually in a record pattern, as in + +data C = C {a :: Int, b :: Int, c :: Int, d :: Int} +f (C {a = 1, b = b, c = c, d = d}) = b + c + d + + + + +Record wildcard syntax permits a (..) in a record +pattern, where each elided field f is replaced by the +pattern f = f. For example, the above pattern can be +written as + +f (C {a = 1, ..}) = b + c + d + + + + +Note that wildcards can be mixed with other patterns, including puns +(); for example, in a pattern C {a += 1, b, ..}). Additionally, record wildcards can be used +wherever record patterns occur, including in let +bindings and at the top-level. For example, the top-level binding + +C {a = 1, ..} = e + +defines b, c, and +d. + + + +Record wildcards can also be used in expressions, writing, for example, + + +let {a = 1; b = 2; c = 3; d = 4} in C {..} + + +in place of + + +let {a = 1; b = 2; c = 3; d = 4} in C {a=a, b=b, c=c, d=d} + + +Note that this expansion is purely syntactic, so the record wildcard +expression refers to the nearest enclosing variables that are spelled +the same as the omitted field names. + + + + + + + +Local Fixity Declarations + + +A careful reading of the Haskell 98 Report reveals that fixity +declarations (infix, infixl, and +infixr) are permitted to appear inside local bindings +such those introduced by let and +where. However, the Haskell Report does not specify +the semantics of such bindings very precisely. + + +In GHC, a fixity declaration may accompany a local binding: + +let f = ... + infixr 3 `f` +in + ... + +and the fixity declaration applies wherever the binding is in scope. +For example, in a let, it applies in the right-hand +sides of other let-bindings and the body of the +letC. Or, in recursive do +expressions (), the local fixity +declarations of aA let statement scope over other +statements in the group, just as the bound name does. + + +Moreover, a local fixity declatation *must* accompany a local binding of +that name: it is not possible to revise the fixity of name bound +elsewhere, as in + +let infixr 9 $ in ... + + +Because local fixity declarations are technically Haskell 98, no flag is +necessary to enable them. + + @@ -3604,7 +3965,10 @@ kind for the type variable cxt. GHC now instead allows you to specify the kind of a type variable directly, wherever -a type variable is explicitly bound. Namely: +a type variable is explicitly bound, with the flag . + + +This flag enables kind signatures in the following places: data declarations: @@ -5306,6 +5670,87 @@ Assertion failures can be caught, see the documentation for the unrecognised word is (silently) ignored. + Certain pragmas are file-header pragmas. A file-header + pragma must precede the module keyword in the file. + There can be as many file-header pragmas as you please, and they can be + preceded or followed by comments. + + + LANGUAGE pragma + + LANGUAGEpragma + pragmaLANGUAGE + + The LANGUAGE pragma allows language extensions to be enabled + in a portable way. + It is the intention that all Haskell compilers support the + LANGUAGE pragma with the same syntax, although not + all extensions are supported by all compilers, of + course. The LANGUAGE pragma should be used instead + of OPTIONS_GHC, if possible. + + For example, to enable the FFI and preprocessing with CPP: + +{-# LANGUAGE ForeignFunctionInterface, CPP #-} + + LANGUAGE is a file-header pragma (see ). + + Every language extension can also be turned into a command-line flag + by prefixing it with "-X"; for example . + (Similarly, all "-X" flags can be written as LANGUAGE pragmas. + + + A list of all supported language extensions can be obtained by invoking + ghc --supported-languages (see ). + + Any extension from the Extension type defined in + Language.Haskell.Extension + may be used. GHC will report an error if any of the requested extensions are not supported. + + + + + OPTIONS_GHC pragma + OPTIONS_GHC + + pragmaOPTIONS_GHC + + + The OPTIONS_GHC pragma is used to specify + additional options that are given to the compiler when compiling + this source file. See for + details. + + Previous versions of GHC accepted OPTIONS rather + than OPTIONS_GHC, but that is now deprecated. + + + OPTIONS_GHC is a file-header pragma (see ). + + + INCLUDE pragma + + The INCLUDE pragma is for specifying the names + of C header files that should be #include'd into + the C source code generated by the compiler for the current module (if + compiling via C). For example: + + +{-# INCLUDE "foo.h" #-} +{-# INCLUDE <stdio.h> #-} + + INCLUDE is a file-header pragma (see ). + + An INCLUDE pragma is the preferred alternative + to the option (), because the + INCLUDE pragma is understood by other + compilers. Yet another alternative is to add the include file to each + foreign import declaration in your code, but we + don't recommend using this approach with GHC. + + DEPRECATED pragma DEPRECATED @@ -5358,31 +5803,6 @@ Assertion failures can be caught, see the documentation for the . - - INCLUDE pragma - - The INCLUDE pragma is for specifying the names - of C header files that should be #include'd into - the C source code generated by the compiler for the current module (if - compiling via C). For example: - - -{-# INCLUDE "foo.h" #-} -{-# INCLUDE <stdio.h> #-} - - The INCLUDE pragma(s) must appear at the top of - your source file with any OPTIONS_GHC - pragma(s). - - An INCLUDE pragma is the preferred alternative - to the option (), because the - INCLUDE pragma is understood by other - compilers. Yet another alternative is to add the include file to each - foreign import declaration in your code, but we - don't recommend using this approach with GHC. - - INLINE and NOINLINE pragmas @@ -5529,29 +5949,6 @@ happen. - - LANGUAGE pragma - - LANGUAGEpragma - pragmaLANGUAGE - - This allows language extensions to be enabled in a portable way. - It is the intention that all Haskell compilers support the - LANGUAGE pragma with the same syntax, although not - all extensions are supported by all compilers, of - course. The LANGUAGE pragma should be used instead - of OPTIONS_GHC, if possible. - - For example, to enable the FFI and preprocessing with CPP: - -{-# LANGUAGE ForeignFunctionInterface, CPP #-} - - Any extension from the Extension type defined in - Language.Haskell.Extension may be used. GHC will report an error if any of the requested extensions are not supported. - - - LINE pragma @@ -5571,22 +5968,6 @@ happen. pragma. - - OPTIONS_GHC pragma - OPTIONS_GHC - - pragmaOPTIONS_GHC - - - The OPTIONS_GHC pragma is used to specify - additional options that are given to the compiler when compiling - this source file. See for - details. - - Previous versions of GHC accepted OPTIONS rather - than OPTIONS_GHC, but that is now deprecated. - - RULES pragma