<para>The Real Truth about what primitive types there are, and what operations
work over those types, is held in the file
-<filename>fptools/ghc/compiler/prelude/primops.txt.pp</filename>.
+<filename>compiler/prelude/primops.txt.pp</filename>.
This file is used directly to generate GHC's primitive-operation definitions, so
it is always correct! It is also intended for processing into text.</para>
-<para> Indeed,
+<para>Indeed,
the result of such processing is part of the description of the
<ulink
url="http://www.haskell.org/ghc/docs/papers/core.ps.gz">External
know and love—usually one instruction.
</para>
+<para> For some primitive types we have special syntax for literals.
+Anything that would be an integer lexeme followed by a
+<literal>#</literal> is an <literal>Int#</literal> literal, e.g.
+<literal>32#</literal> and <literal>-0x3A#</literal>. Likewise,
+any non-negative integer literal followed by
+<literal>##</literal> is a <literal>Word#</literal> literal.
+Likewise, any floating point literal followed by a
+<literal>#</literal> is a <literal>Float#</literal> literal, and
+followed by <literal>##</literal> is a
+<literal>Double#</literal>. Finally, a string literal followed by a
+<literal>#</literal>, e.g. <literal>"foo"#</literal>,
+is a <literal>Addr#</literal> literal.
+</para>
+
<para>
Primitive (unboxed) types cannot be defined in Haskell, and are
therefore built into the language and compiler. Primitive types are
<replaceable>word</replaceable> that GHC understands are described
in the following sections; any pragma encountered with an
unrecognised <replaceable>word</replaceable> is (silently)
- ignored.</para>
+ ignored. The layout rule applies in pragmas, so the closing <literal>#-}</literal>
+ should start in a column to the right of the opening <literal>{-#</literal>. </para>
<para>Certain pragmas are <emphasis>file-header pragmas</emphasis>. A file-header
pragma must precede the <literal>module</literal> keyword in the file.
<programlisting>
{-# RULES
- "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
- #-}
+ "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
+ #-}
</programlisting>
-
</para>
<sect2>
From a syntactic point of view:
<itemizedlist>
-<listitem>
+<listitem>
<para>
- There may be zero or more rules in a <literal>RULES</literal> pragma.
+ There may be zero or more rules in a <literal>RULES</literal> pragma, separated by semicolons (which
+ may be generated by the layout rule).
</para>
</listitem>
<listitem>
+<para>
+The layout rule applies in a pragma.
+Currently no new indentation level
+is set, so if you put several rules in single RULES pragma and wish to use layout to separate them,
+you must lay out the starting in the same column as the enclosing definitions.
+<programlisting>
+ {-# RULES
+ "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
+ "map/append" forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys
+ #-}
+</programlisting>
+Furthermore, the closing <literal>#-}</literal>
+should start in a column to the right of the opening <literal>{-#</literal>.
+</para>
+</listitem>
+<listitem>
<para>
Each rule has a name, enclosed in double quotes. The name itself has
no significance at all. It is only used when reporting how many times the rule fired.
<programlisting>
{-# RULES
"map/map" [2] forall f g xs. map f (map g xs) = map (f.g) xs
- #-}
+ #-}
</programlisting>
The "[2]" means that the rule is active in Phase 2 and subsequent phases. The inverse
notation "[~2]" is also accepted, meaning that the rule is active up to, but not including,
</listitem>
-<listitem>
-
-<para>
- Layout applies in a <literal>RULES</literal> pragma. Currently no new indentation level
-is set, so you must lay out your rules starting in the same column as the
-enclosing definitions.
-</para>
-</listitem>
<listitem>
-
<para>
Each variable mentioned in a rule must either be in scope (e.g. <function>map</function>),
or bound by the <literal>forall</literal> (e.g. <function>f</function>, <function>g</function>, <function>xs</function>). The variables bound by