X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=c9e6183d0491d952d530058b2bb187132811985c;hb=1fe5459fe14758dbbc6106f616446f43e21a0511;hp=3b83551e1276bcd2b9a71c676abbebdb756daa2c;hpb=5e04ae341a945ef430e9d941b34722b8de1f6aae;p=ghc-hetmet.git diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 3b83551..c9e6183 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -290,6 +290,17 @@ documentation describes all the libraries that come with GHC. + + + + Enables quasiquotation (see ). + + Syntax stolen: + [:varid|. + + + @@ -2400,7 +2411,7 @@ may use different notation to that implemented in GHC. The rest of this section outlines the extensions to GHC that support GADTs. The extension is enabled with -. +. The flag also sets . A GADT can only be declared using GADT-style syntax (); @@ -4544,7 +4555,7 @@ a type for ys; a major benefit of scoped type variables is th it becomes possible to do so. Lexically-scoped type variables are enabled by -. +. This flag implies . Note: GHC 6.6 contains substantial changes to the way that scoped type variables work, compared to earlier releases. Read this section @@ -4602,7 +4613,7 @@ then A declaration type signature that has explicit quantification (using forall) brings into scope the explicitly-quantified -type variables, in the definition of the named function(s). For example: +type variables, in the definition of the named function. For example: f :: forall a. [a] -> [a] f (x:xs) = xs ++ [ x :: a ] @@ -4610,7 +4621,9 @@ type variables, in the definition of the named function(s). For example: The "forall a" brings "a" into scope in the definition of "f". -This only happens if the quantification in f's type +This only happens if: + + The quantification in f's type signature is explicit. For example: g :: [a] -> [a] @@ -4620,6 +4633,26 @@ This program will be rejected, because "a" does not scope over the definition of "f", so "x::a" means "x::forall a. a" by Haskell's usual implicit quantification rules. + + The signature gives a type for a function binding or a bare variable binding, +not a pattern binding. +For example: + + f1 :: forall a. [a] -> [a] + f1 (x:xs) = xs ++ [ x :: a ] -- OK + + f2 :: forall a. [a] -> [a] + f2 = \(x:xs) -> xs ++ [ x :: a ] -- OK + + f3 :: forall a. [a] -> [a] + Just f3 = Just (\(x:xs) -> xs ++ [ x :: a ]) -- Not OK! + +The binding for f3 is a pattern binding, and so its type signature +does not bring a into scope. However f1 is a +function binding, and f2 binds a bare variable; in both cases +the type signature brings a into scope. + + @@ -4963,6 +4996,15 @@ Wiki page. + A quasi-quotation can appear in either a pattern context or an + expression context and is also written in Oxford brackets: + + [:varid| ... |], + where the "..." is an arbitrary string; a full description of the + quasi-quotation facility is given in . + + + A name can be quoted with either one or two prefix single quotes: 'f has type Name, and names the function f. @@ -5136,6 +5178,124 @@ The basic idea is to compile the program twice: + Template Haskell Quasi-quotation +Quasi-quotation allows patterns and expressions to be written using +programmer-defined concrete syntax; the motivation behind the extension and +several examples are documented in +"Why It's +Nice to be Quoted: Quasiquoting for Haskell" (Proc Haskell Workshop +2007). The example below shows how to write a quasiquoter for a simple +expression language. + + +In the example, the quasiquoter expr is bound to a value of +type Language.Haskell.TH.Quote.QuasiQuoter which contains two +functions for quoting expressions and patterns, respectively. The first argument +to each quoter is the (arbitrary) string enclosed in the Oxford brackets. The +context of the quasi-quotation statement determines which of the two parsers is +called: if the quasi-quotation occurs in an expression context, the expression +parser is called, and if it occurs in a pattern context, the pattern parser is +called. + + +Note that in the example we make use of an antiquoted +variable n, indicated by the syntax 'int:n +(this syntax for anti-quotation was defined by the parser's +author, not by GHC). This binds n to the +integer value argument of the constructor IntExpr when +pattern matching. Please see the referenced paper for further details regarding +anti-quotation as well as the description of a technique that uses SYB to +leverage a single parser of type String -> a to generate both +an expression parser that returns a value of type Q Exp and a +pattern parser that returns a value of type Q Pat. + + +In general, a quasi-quote has the form +[$quoter| string |]. +The quoter must be the name of an imported quoter; it +cannot be an arbitrary expression. The quoted string +can be arbitrary, and may contain newlines. + + +Quasiquoters must obey the same stage restrictions as Template Haskell, e.g., in +the example, expr cannot be defined +in Main.hs where it is used, but must be imported. + + + + +{- Main.hs -} +module Main where + +import Expr + +main :: IO () +main = do { print $ eval [$expr|1 + 2|] + ; case IntExpr 1 of + { [$expr|'int:n|] -> print n + ; _ -> return () + } + } + + +{- Expr.hs -} +module Expr where + +import qualified Language.Haskell.TH as TH +import Language.Haskell.TH.Quasi + +data Expr = IntExpr Integer + | AntiIntExpr String + | BinopExpr BinOp Expr Expr + | AntiExpr String + deriving(Show, Typeable, Data) + +data BinOp = AddOp + | SubOp + | MulOp + | DivOp + deriving(Show, Typeable, Data) + +eval :: Expr -> Integer +eval (IntExpr n) = n +eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y) + where + opToFun AddOp = (+) + opToFun SubOp = (-) + opToFun MulOp = (*) + opToFun DivOp = div + +expr = QuasiQuoter parseExprExp parseExprPat + +-- Parse an Expr, returning its representation as +-- either a Q Exp or a Q Pat. See the referenced paper +-- for how to use SYB to do this by writing a single +-- parser of type String -> Expr instead of two +-- separate parsers. + +parseExprExp :: String -> Q Exp +parseExprExp ... + +parseExprPat :: String -> Q Pat +parseExprPat ... + + +Now run the compiler: + + +$ ghc --make -XQuasiQuotes Main.hs -o main + + +Run "main" and here is your output: + + +$ ./main +3 +1 + + + + @@ -6149,7 +6309,7 @@ exactly what you asked for, no more and no less. there was no pragma). - "INLINE[~k] f" means: be willing to inline + "NOINLINE[~k] f" means: be willing to inline f until phase k, but from phase k onwards do not inline it.