Add quasi-quotation, courtesy of Geoffrey Mainland
[ghc-hetmet.git] / docs / users_guide / glasgow_exts.xml
index a1cf5c5..f22e6c9 100644 (file)
@@ -290,6 +290,17 @@ documentation</ulink> describes all the libraries that come with GHC.
        </listitem>
       </varlistentry>
 
+      <varlistentry>
+       <term><option>-XQuasiQuotes</option></term>
+       <listitem>
+         <para>Enables quasiquotation (see <xref
+         linkend="th-quasiquotation"/>).</para>
+
+         <para>Syntax stolen:
+         <literal>[:<replaceable>varid</replaceable>|</literal>.</para>
+       </listitem>
+      </varlistentry>
+
     </variablelist>
   </sect1>
 
@@ -1058,6 +1069,166 @@ This name is not supported by GHC.
     branches.</para>
 
   </sect2>
+  
+  <!-- ===================== TRANSFORM LIST COMPREHENSIONS ===================  -->
+
+  <sect2 id="generalised-list-comprehensions">
+    <title>Generalised (SQL-Like) List Comprehensions</title>
+    <indexterm><primary>list comprehensions</primary><secondary>generalised</secondary>
+    </indexterm>
+    <indexterm><primary>extended list comprehensions</primary>
+    </indexterm>
+    <indexterm><primary>group</primary></indexterm>
+    <indexterm><primary>sql</primary></indexterm>
+
+
+    <para>Generalised list comprehensions are a further enhancement to the
+    list comprehension syntatic sugar to allow operations such as sorting
+    and grouping which are familiar from SQL.   They are fully described in the
+       paper <ulink url="http://research.microsoft.com/~simonpj/papers/list-comp">
+         Comprehensive comprehensions: comprehensions with "order by" and "group by"</ulink>,
+    except that the syntax we use differs slightly from the paper.</para>
+<para>Here is an example: 
+<programlisting>
+employees = [ ("Simon", "MS", 80)
+, ("Erik", "MS", 100)
+, ("Phil", "Ed", 40)
+, ("Gordon", "Ed", 45)
+, ("Paul", "Yale", 60)]
+
+output = [ (the dept, sum salary)
+| (name, dept, salary) &lt;- employees
+, then group by dept
+, then sortWith by (sum salary)
+, then take 5 ]
+</programlisting>
+In this example, the list <literal>output</literal> would take on 
+    the value:
+    
+<programlisting>
+[("Yale", 60), ("Ed", 85), ("MS", 180)]
+</programlisting>
+</para>
+<para>There are three new keywords: <literal>group</literal>, <literal>by</literal>, and <literal>using</literal>.
+(The function <literal>sortWith</literal> is not a keyword; it is an ordinary
+function that is exported by <literal>GHC.Exts</literal>.)</para>
+
+<para>There are five new forms of compehension qualifier,
+all introduced by the (existing) keyword <literal>then</literal>:
+    <itemizedlist>
+    <listitem>
+    
+<programlisting>
+then f
+</programlisting>
+
+    This statement requires that <literal>f</literal> have the type <literal>
+    forall a. [a] -> [a]</literal>. You can see an example of it's use in the
+    motivating example, as this form is used to apply <literal>take 5</literal>.
+    
+    </listitem>
+    
+    
+    <listitem>
+<para>
+<programlisting>
+then f by e
+</programlisting>
+
+    This form is similar to the previous one, but allows you to create a function
+    which will be passed as the first argument to f. As a consequence f must have 
+    the type <literal>forall a. (a -> t) -> [a] -> [a]</literal>. As you can see
+    from the type, this function lets f &quot;project out&quot; some information 
+    from the elements of the list it is transforming.</para>
+
+    <para>An example is shown in the opening example, where <literal>sortWith</literal> 
+    is supplied with a function that lets it find out the <literal>sum salary</literal> 
+    for any item in the list comprehension it transforms.</para>
+
+    </listitem>
+
+
+    <listitem>
+
+<programlisting>
+then group by e using f
+</programlisting>
+
+    <para>This is the most general of the grouping-type statements. In this form,
+    f is required to have type <literal>forall a. (a -> t) -> [a] -> [[a]]</literal>.
+    As with the <literal>then f by e</literal> case above, the first argument
+    is a function supplied to f by the compiler which lets it compute e on every
+    element of the list being transformed. However, unlike the non-grouping case,
+    f additionally partitions the list into a number of sublists: this means that
+    at every point after this statement, binders occuring before it in the comprehension
+    refer to <emphasis>lists</emphasis> of possible values, not single values. To help understand
+    this, let's look at an example:</para>
+    
+<programlisting>
+-- This works similarly to groupWith in GHC.Exts, but doesn't sort its input first
+groupRuns :: Eq b => (a -> b) -> [a] -> [[a]]
+groupRuns f = groupBy (\x y -> f x == f y)
+
+output = [ (the x, y)
+| x &lt;- ([1..3] ++ [1..2])
+, y &lt;- [4..6]
+, then group by x using groupRuns ]
+</programlisting>
+
+    <para>This results in the variable <literal>output</literal> taking on the value below:</para>
+
+<programlisting>
+[(1, [4, 5, 6]), (2, [4, 5, 6]), (3, [4, 5, 6]), (1, [4, 5, 6]), (2, [4, 5, 6])]
+</programlisting>
+
+    <para>Note that we have used the <literal>the</literal> function to change the type 
+    of x from a list to its original numeric type. The variable y, in contrast, is left 
+    unchanged from the list form introduced by the grouping.</para>
+
+    </listitem>
+
+    <listitem>
+
+<programlisting>
+then group by e
+</programlisting>
+
+    <para>This form of grouping is essentially the same as the one described above. However,
+    since no function to use for the grouping has been supplied it will fall back on the
+    <literal>groupWith</literal> function defined in 
+    <ulink url="../libraries/base/GHC-Exts.html"><literal>GHC.Exts</literal></ulink>. This
+    is the form of the group statement that we made use of in the opening example.</para>
+
+    </listitem>
+    
+    
+    <listitem>
+
+<programlisting>
+then group using f
+</programlisting>
+
+    <para>With this form of the group statement, f is required to simply have the type
+    <literal>forall a. [a] -> [[a]]</literal>, which will be used to group up the
+    comprehension so far directly. An example of this form is as follows:</para>
+    
+<programlisting>
+output = [ x
+| y &lt;- [1..5]
+, x &lt;- "hello"
+, then group using inits]
+</programlisting>
+
+    <para>This will yield a list containing every prefix of the word "hello" written out 5 times:</para>
+
+<programlisting>
+["","h","he","hel","hell","hello","helloh","hellohe","hellohel","hellohell","hellohello","hellohelloh",...]
+</programlisting>
+
+    </listitem>
+</itemizedlist>
+</para>
+  </sect2>
 
    <!-- ===================== REBINDABLE SYNTAX ===================  -->
 
@@ -2240,7 +2411,7 @@ may use different notation to that implemented in GHC.
 </para>
 <para>
 The rest of this section outlines the extensions to GHC that support GADTs.   The extension is enabled with 
-<option>-XGADTs</option>.
+<option>-XGADTs</option>.  The <option>-XGADTs</option> flag also sets <option>-XRelaxedPolyRec</option>.
 <itemizedlist>
 <listitem><para>
 A GADT can only be declared using GADT-style syntax (<xref linkend="gadt-style"/>); 
@@ -4341,7 +4512,9 @@ for rank-2 types.
 <sect2 id="impredicative-polymorphism">
 <title>Impredicative polymorphism
 </title>
-<para>GHC supports <emphasis>impredicative polymorphism</emphasis>.  This means
+<para>GHC supports <emphasis>impredicative polymorphism</emphasis>, 
+enabled with <option>-XImpredicativeTypes</option>.  
+This means
 that you can call a polymorphic function at a polymorphic type, and
 parameterise data structures over polymorphic types.  For example:
 <programlisting>
@@ -4382,7 +4555,7 @@ a type for <varname>ys</varname>; a major benefit of scoped type variables is th
 it becomes possible to do so.
 </para>
 <para>Lexically-scoped type variables are enabled by
-<option>-fglasgow-exts</option>.
+<option>-XScopedTypeVariables</option>.  This flag implies <option>-XRelaxedPolyRec</option>.
 </para>
 <para>Note: GHC 6.6 contains substantial changes to the way that scoped type
 variables work, compared to earlier releases.  Read this section
@@ -4440,7 +4613,7 @@ then
 <para>A declaration type signature that has <emphasis>explicit</emphasis>
 quantification (using <literal>forall</literal>) 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:
 <programlisting>
   f :: forall a. [a] -> [a]
   f (x:xs) = xs ++ [ x :: a ]
@@ -4448,7 +4621,9 @@ type variables, in the definition of the named function(s).  For example:
 The "<literal>forall a</literal>" brings "<literal>a</literal>" into scope in
 the definition of "<literal>f</literal>".
 </para>
-<para>This only happens if the quantification in <literal>f</literal>'s type
+<para>This only happens if:
+<itemizedlist>
+<listitem><para> The quantification in <literal>f</literal>'s type
 signature is explicit.  For example:
 <programlisting>
   g :: [a] -> [a]
@@ -4458,6 +4633,26 @@ This program will be rejected, because "<literal>a</literal>" does not scope
 over the definition of "<literal>f</literal>", so "<literal>x::a</literal>"
 means "<literal>x::forall a. a</literal>" by Haskell's usual implicit
 quantification rules.
+</para></listitem>
+<listitem><para> The signature gives a type for a function binding or a bare variable binding, 
+not a pattern binding.
+For example:
+<programlisting>
+  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!
+</programlisting>
+The binding for <literal>f3</literal> is a pattern binding, and so its type signature
+does not bring <literal>a</literal> into scope.   However <literal>f1</literal> is a
+function binding, and <literal>f2</literal> binds a bare variable; in both cases
+the type signature brings <literal>a</literal> into scope.
+</para></listitem>
+</itemizedlist>
 </para>
 </sect3>
 
@@ -4801,6 +4996,15 @@ Wiki page</ulink>.
                  </itemizedlist></para></listitem>
 
              <listitem><para>
+                 A quasi-quotation can appear in either a pattern context or an
+                 expression context and is also written in Oxford brackets:
+                 <itemizedlist>
+                   <listitem><para> <literal>[:<replaceable>varid</replaceable>| ... |]</literal>,
+                        where the "..." is an arbitrary string; a full description of the
+                       quasi-quotation facility is given in <xref linkend="th-quasiquotation"/>.</para></listitem>
+                 </itemizedlist></para></listitem>
+
+             <listitem><para>
                  A name can be quoted with either one or two prefix single quotes:
                  <itemizedlist>
                    <listitem><para> <literal>'f</literal> has type <literal>Name</literal>, and names the function <literal>f</literal>.
@@ -4840,9 +5044,13 @@ Type splices are not implemented, and neither are pattern splices or quotations.
    </para></listitem>
 
    <listitem><para>
-   Furthermore, you can only run a function at compile time if it is imported
+   You can only run a function at compile time if it is imported
    from another module <emphasis>that is not part of a mutually-recursive group of modules
-   that includes the module currently being compiled</emphasis>.  For example, when compiling module A,
+   that includes the module currently being compiled</emphasis>.  Furthermore, all of the modules of 
+   the mutually-recursive group must be reachable by non-SOURCE imports from the module where the
+   splice is to be run.</para>
+   <para>
+   For example, when compiling module A,
    you can only run Template Haskell functions imported from B if B does not import A (directly or indirectly).
    The reason should be clear: to run B we must compile and run A, but we are currently type-checking A.
    </para></listitem>
@@ -4970,6 +5178,124 @@ The basic idea is to compile the program twice:</para>
 </orderedlist>
 </sect2>
 
+<sect2 id="th-quasiquotation">  <title> Template Haskell Quasi-quotation </title>
+<para>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
+"<ulink url="http://www.eecs.harvard.edu/~mainland/ghc-quasiquoting/">Why It's
+Nice to be Quoted: Quasiquoting for Haskell</ulink>" (Proc Haskell Workshop
+2007). The example below shows how to write a quasiquoter for a simple
+expression language.</para>
+
+<para>
+In the example, the quasiquoter <literal>expr</literal> is bound to a value of
+type <literal>Language.Haskell.TH.Quote.QuasiQuoter</literal> 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.</para>
+
+<para>
+Note that in the example we make use of an antiquoted
+variable <literal>n</literal>, indicated by the syntax <literal>'int:n</literal>
+(this syntax for anti-quotation was defined by the parser's
+author, <emphasis>not</emphasis> by GHC). This binds <literal>n</literal> to the
+integer value argument of the constructor <literal>IntExpr</literal> 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 <literal>String -> a</literal> to generate both
+an expression parser that returns a value of type <literal>Q Exp</literal> and a
+pattern parser that returns a value of type <literal>Q Pat</literal>.
+</para>
+
+<para>In general, a quasi-quote has the form
+<literal>[$<replaceable>quoter</replaceable>| <replaceable>string</replaceable> |]</literal>.
+The <replaceable>quoter</replaceable> must be the name of an imported quoter; it
+cannot be an arbitrary expression.  The quoted <replaceable>string</replaceable> 
+can be arbitrary, and may contain newlines.
+</para>
+<para>
+Quasiquoters must obey the same stage restrictions as Template Haskell, e.g., in
+the example, <literal>expr</literal> cannot be defined
+in <literal>Main.hs</literal> where it is used, but must be imported.
+</para>
+
+<programlisting>
+
+{- 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 ...
+</programlisting>
+
+<para>Now run the compiler:
+</para>
+<programlisting>
+$ ghc --make -XQuasiQuotes Main.hs -o main
+</programlisting>
+
+<para>Run "main" and here is your output:</para>
+
+<programlisting>
+$ ./main
+3
+1
+</programlisting>
+
+</sect2>
+
 </sect1>
 
 <!-- ===================== Arrow notation ===================  -->
@@ -6214,14 +6540,14 @@ data T = T {-# UNPACK #-} !(Int,Int)
 
       <para>will store the two <literal>Int</literal>s directly in the
       <function>T</function> constructor, by flattening the pair.
-      Multi-level unpacking is also supported:</para>
+      Multi-level unpacking is also supported:
 
 <programlisting>
 data T = T {-# UNPACK #-} !S
 data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
 </programlisting>
 
-      <para>will store two unboxed <literal>Int&num;</literal>s
+      will store two unboxed <literal>Int&num;</literal>s
       directly in the <function>T</function> constructor.  The
       unpacker can see through newtypes, too.</para>
 
@@ -6235,6 +6561,15 @@ data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
       constructor field.</para>
     </sect2>
 
+    <sect2 id="source-pragma">
+      <title>SOURCE pragma</title>
+
+      <indexterm><primary>SOURCE</primary></indexterm>
+     <para>The <literal>{-# SOURCE #-}</literal> pragma is used only in <literal>import</literal> declarations,
+     to break a module loop.  It is described in detail in <xref linkend="mutual-recursion"/>.
+     </para>
+</sect2>
+
 </sect1>
 
 <!--  ======================= REWRITE RULES ======================== -->