<entry>Name</entry>
</row>
</thead>
+
+<!--
+ to find the DocBook entities for these characters, find
+ the Unicode code point (e.g. 0x2237), and grep for it in
+ /usr/share/sgml/docbook/xml-dtd-*/ent/* (or equivalent on
+ your system. Some of these Unicode code points don't have
+ equivalent DocBook entities.
+ -->
+
<tbody>
<row>
<entry><literal>::</literal></entry>
<entry>MIDLINE HORIZONTAL ELLIPSIS</entry>
</row>
</tbody>
+
+ <tbody>
+ <row>
+ <entry>-<</entry>
+ <entry>↢</entry>
+ <entry>0x2919</entry>
+ <entry>LEFTWARDS ARROW-TAIL</entry>
+ </row>
+ </tbody>
+
+ <tbody>
+ <row>
+ <entry>>-</entry>
+ <entry>↣</entry>
+ <entry>0x291A</entry>
+ <entry>RIGHTWARDS ARROW-TAIL</entry>
+ </row>
+ </tbody>
+
+ <tbody>
+ <row>
+ <entry>-<<</entry>
+ <entry></entry>
+ <entry>0x291B</entry>
+ <entry>LEFTWARDS DOUBLE ARROW-TAIL</entry>
+ </row>
+ </tbody>
+
+ <tbody>
+ <row>
+ <entry>>>-</entry>
+ <entry></entry>
+ <entry>0x291C</entry>
+ <entry>RIGHTWARDS DOUBLE ARROW-TAIL</entry>
+ </row>
+ </tbody>
+
+ <tbody>
+ <row>
+ <entry>*</entry>
+ <entry>★</entry>
+ <entry>0x2605</entry>
+ <entry>BLACK STAR</entry>
+ </row>
+ </tbody>
+
</tgroup>
</informaltable>
</sect2>
<sect3> <title> Mdo-notation (deprecated) </title>
-<para> GHC used to support the flag <option>-XREecursiveDo</option>,
+<para> GHC used to support the flag <option>-XRecursiveDo</option>,
which enabled the keyword <literal>mdo</literal>, precisely as described in
<ulink url="http://sites.google.com/site/leventerkok/">A recursive do for Haskell</ulink>,
but this is now deprecated. Instead of <literal>mdo { Q; e }</literal>, write
(You need <link linkend="instance-rules"><option>-XFlexibleInstances</option></link> to do this.)
</para>
<para>
+Warning: overlapping instances must be used with care. They
+can give rise to incoherence (ie different instance choices are made
+in different parts of the program) even without <option>-XIncoherentInstances</option>. Consider:
+<programlisting>
+{-# LANGUAGE OverlappingInstances #-}
+module Help where
+
+ class MyShow a where
+ myshow :: a -> String
+
+ instance MyShow a => MyShow [a] where
+ myshow xs = concatMap myshow xs
+
+ showHelp :: MyShow a => [a] -> String
+ showHelp xs = myshow xs
+
+{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}
+module Main where
+ import Help
+
+ data T = MkT
+
+ instance MyShow T where
+ myshow x = "Used generic instance"
+
+ instance MyShow [T] where
+ myshow xs = "Used more specific instance"
+
+ main = do { print (myshow [MkT]); print (showHelp [MkT]) }
+</programlisting>
+In function <literal>showHelp</literal> GHC sees no overlapping
+instances, and so uses the <literal>MyShow [a]</literal> instance
+without complaint. In the call to <literal>myshow</literal> in <literal>main</literal>,
+GHC resolves the <literal>MyShow [T]</literal> constraint using the overlapping
+instance declaration in module <literal>Main</literal>. As a result,
+the program prints
+<programlisting>
+ "Used more specific instance"
+ "Used generic instance"
+</programlisting>
+(An alternative possible behaviour, not currently implemented,
+would be to reject module <literal>Help</literal>
+on the grounds that a later instance declaration might overlap the local one.)
+</para>
+<para>
The willingness to be overlapped or incoherent is a property of
the <emphasis>instance declaration</emphasis> itself, controlled by the
presence or otherwise of the <option>-XOverlappingInstances</option>
<listitem><para> a list of top-level declarations; the spliced expression
must have type <literal>Q [Dec]</literal></para></listitem>
</itemizedlist>
+ Note that pattern splices are not supported.
Inside a splice you can can only call functions defined in imported modules,
- not functions defined elsewhere in the same module.</para></listitem>
+ not functions defined elsewhere in the same module.</para></listitem>
<listitem><para>
A expression quotation is written in Oxford brackets, thus:
<itemizedlist>
- <listitem><para> <literal>[| ... |]</literal>, where the "..." is an expression;
+ <listitem><para> <literal>[| ... |]</literal>, or <literal>[e| ... |]</literal>,
+ where the "..." is an expression;
the quotation has type <literal>Q Exp</literal>.</para></listitem>
<listitem><para> <literal>[d| ... |]</literal>, where the "..." is a list of top-level declarations;
the quotation has type <literal>Q [Dec]</literal>.</para></listitem>
<listitem><para> <literal>[t| ... |]</literal>, where the "..." is a type;
- the quotation has type <literal>Q Typ</literal>.</para></listitem>
+ the quotation has type <literal>Q Type</literal>.</para></listitem>
+ <listitem><para> <literal>[p| ... |]</literal>, where the "..." is a pattern;
+ the quotation has type <literal>Q Pat</literal>.</para></listitem>
</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>,
+ <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>
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>
+Here are the salient features
+<itemizedlist>
+<listitem><para>
+A quasi-quote has the form
+<literal>[<replaceable>quoter</replaceable>| <replaceable>string</replaceable> |]</literal>.
+<itemizedlist>
+<listitem><para>
+The <replaceable>quoter</replaceable> must be the (unqualified) name of an imported
+quoter; it cannot be an arbitrary expression.
+</para></listitem>
+<listitem><para>
+The <replaceable>quoter</replaceable> cannot be "<literal>e</literal>",
+"<literal>t</literal>", "<literal>d</literal>", or "<literal>p</literal>", since
+those overlap with Template Haskell quotations.
+</para></listitem>
+<listitem><para>
+There must be no spaces in the token
+<literal>[<replaceable>quoter</replaceable>|</literal>.
+</para></listitem>
+<listitem><para>
+The quoted <replaceable>string</replaceable>
+can be arbitrary, and may contain newlines.
+</para></listitem>
+</itemizedlist>
+</para></listitem>
+
+<listitem><para>
+A quasiquote may appear in place of
+<itemizedlist>
+<listitem><para>An expression</para></listitem>
+<listitem><para>A pattern</para></listitem>
+<listitem><para>A type</para></listitem>
+<listitem><para>A top-level declaration</para></listitem>
+</itemizedlist>
+(Only the first two are described in the paper.)
+</para></listitem>
+<listitem><para>
+A quoter is a value of type <literal>Language.Haskell.TH.Quote.QuasiQuoter</literal>,
+which is defined thus:
+<programlisting>
+data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp,
+ quotePat :: String -> Q Pat,
+ quoteType :: String -> Q Type,
+ quoteDec :: String -> Q [Dec] }
+</programlisting>
+That is, a quoter is a tuple of four parsers, one for each of the contexts
+in which a quasi-quote can occur.
+</para></listitem>
+<listitem><para>
+A quasi-quote is expanded by applying the appropriate parser to the string
+enclosed by the Oxford brackets. The context of the quasi-quote (expression, pattern,
+type, declaration) determines which of the parsers is called.
+</para></listitem>
+</itemizedlist>
+</para>
<para>
-Note that in the example we make use of an antiquoted
+The example below shows quasi-quotation in action. The quoter <literal>expr</literal>
+is bound to a value of type <literal>QuasiQuoter</literal> defined in module <literal>Expr</literal>.
+The example makes 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
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
</para>
<programlisting>
-
-{- Main.hs -}
+{- ------------- file Main.hs --------------- -}
module Main where
import Expr
main :: IO ()
-main = do { print $ eval [$expr|1 + 2|]
+main = do { print $ eval [expr|1 + 2|]
; case IntExpr 1 of
- { [$expr|'int:n|] -> print n
+ { [expr|'int:n|] -> print n
; _ -> return ()
}
}
-{- Expr.hs -}
+{- ------------- file Expr.hs --------------- -}
module Expr where
import qualified Language.Haskell.TH as TH
opToFun MulOp = (*)
opToFun DivOp = div
-expr = QuasiQuoter parseExprExp parseExprPat
+expr = QuasiQuoter { quoteExp = parseExprExp, quotePat = parseExprPat }
-- Parse an Expr, returning its representation as
-- either a Q Exp or a Q Pat. See the referenced paper
</programlisting>
<para>Now run the compiler:
-</para>
<programlisting>
$ ghc --make -XQuasiQuotes Main.hs -o main
</programlisting>
+</para>
-<para>Run "main" and here is your output:</para>
-
+<para>Run "main" and here is your output:
<programlisting>
$ ./main
3
1
</programlisting>
-
+</para>
</sect2>
</sect1>
portable).</para>
</sect3>
+ <sect3 id="conlike-pragma">
+ <title>CONLIKE modifier</title>
+ <indexterm><primary>CONLIKE</primary></indexterm>
+ <para>An INLINE or NOINLINE pragma may have a CONLIKE modifier,
+ which affects matching in RULEs (only). See <xref linkend="conlike"/>.
+ </para>
+ </sect3>
+
<sect3 id="phase-control">
<title>Phase control</title>
</para>
</listitem>
-<listitem>
+</itemizedlist>
+
+</para>
+
+</sect2>
+
+<sect2 id="conlike">
+<title>How rules interact with INLINE/NOINLINE and CONLIKE pragmas</title>
<para>
Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected
results. Consider this (artificial) example
<programlisting>
f x = x
-{-# RULES "f" f True = False #-}
-
g y = f y
-
h z = g True
+
+{-# RULES "f" f True = False #-}
</programlisting>
Since <literal>f</literal>'s right-hand side is small, it is inlined into <literal>g</literal>,
to give
</para>
<para>
The way to get predictable behaviour is to use a NOINLINE
-pragma on <literal>f</literal>, to ensure
+pragma, or an INLINE[<replaceable>phase</replaceable>] pragma, on <literal>f</literal>, to ensure
that it is not inlined until its RULEs have had a chance to fire.
</para>
-</listitem>
-</itemizedlist>
-
+<para>
+GHC is very cautious about duplicating work. For example, consider
+<programlisting>
+f k z xs = let xs = build g
+ in ...(foldr k z xs)...sum xs...
+{-# RULES "foldr/build" forall k z g. foldr k z (build g) = g k z #-}
+</programlisting>
+Since <literal>xs</literal> is used twice, GHC does not fire the foldr/build rule. Rightly
+so, because it might take a lot of work to compute <literal>xs</literal>, which would be
+duplicated if the rule fired.
+</para>
+<para>
+Sometimes, however, this approach is over-cautious, and we <emphasis>do</emphasis> want the
+rule to fire, even though doing so would duplicate redex. There is no way that GHC can work out
+when this is a good idea, so we provide the CONLIKE pragma to declare it, thus:
+<programlisting>
+{-# INLINE[1] CONLIKE f #-}
+f x = <replaceable>blah</replaceable>
+</programlisting>
+CONLIKE is a modifier to an INLINE or NOINLINE pragam. It specifies that an application
+of f to one argument (in general, the number of arguments to the left of the '=' sign)
+should be considered cheap enough to duplicate, if such a duplication would make rule
+fire. (The name "CONLIKE" is short for "constructor-like", because constructors certainly
+have such a property.)
+The CONLIKE pragam is a modifier to INLINE/NOINLINE because it really only makes sense to match
+<literal>f</literal> on the LHS of a rule if you are sure that <literal>f</literal> is
+not going to be inlined before the rule has a chance to fire.
</para>
-
</sect2>
<sect2>
</sect2>
-<sect2>
-<title>Controlling what's going on</title>
+<sect2 id="controlling-rules">
+<title>Controlling what's going on in rewrite rules</title>
<para>
<listitem>
<para>
- Use <option>-ddump-rules</option> to see what transformation rules GHC is using.
+Use <option>-ddump-rules</option> to see the rules that are defined
+<emphasis>in this module</emphasis>.
+This includes rules generated by the specialisation pass, but excludes
+rules imported from other modules.
</para>
</listitem>
-<listitem>
+<listitem>
<para>
Use <option>-ddump-simpl-stats</option> to see what rules are being fired.
If you add <option>-dppr-debug</option> you get a more detailed listing.
</para>
</listitem>
+
<listitem>
+<para>
+ Use <option>-ddump-rule-firings</option> to see in great detail what rules are being fired.
+If you add <option>-dppr-debug</option> you get a still more detailed listing.
+</para>
+</listitem>
+<listitem>
<para>
The definition of (say) <function>build</function> in <filename>GHC/Base.lhs</filename> looks like this: