<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
</title>
<para>
-Record puns are enabled by the flag <literal>-XRecordPuns</literal>.
+Record puns are enabled by the flag <literal>-XNamedFieldPuns</literal>.
</para>
<para>
but for a GADT the arguments to the type constructor can be arbitrary monotypes.
For example, in the <literal>Term</literal> data
type above, the type of each constructor must end with <literal>Term ty</literal>, but
-the <literal>ty</literal> may not be a type variable (e.g. the <literal>Lit</literal>
+the <literal>ty</literal> need not be a type variable (e.g. the <literal>Lit</literal>
constructor).
</para></listitem>
<listitem><para>
+It's is permitted to declare an ordinary algebraic data type using GADT-style syntax.
+What makes a GADT into a GADT is not the syntax, but rather the presence of data constructors
+whose result type is not just <literal>T a b</literal>.
+</para></listitem>
+
+<listitem><para>
You cannot use a <literal>deriving</literal> clause for a GADT; only for
an ordinary data type.
</para></listitem>
</programlisting>
</para></listitem>
+<listitem><para>
+When pattern-matching against data constructors drawn from a GADT,
+for example in a <literal>case</literal> expression, the following rules apply:
+<itemizedlist>
+<listitem><para>The type of the scrutinee must be rigid.</para></listitem>
+<listitem><para>The type of the result of the <literal>case</literal> expression must be rigid.</para></listitem>
+<listitem><para>The type of any free variable mentioned in any of
+the <literal>case</literal> alternatives must be rigid.</para></listitem>
+</itemizedlist>
+A type is "rigid" if it is completely known to the compiler at its binding site. The easiest
+way to ensure that a variable a rigid type is to give it a type signature.
+</para></listitem>
+
</itemizedlist>
</para>
You must supply a context (in the example the context is <literal>(Eq a)</literal>),
exactly as you would in an ordinary instance declaration.
(In contrast the context is inferred in a <literal>deriving</literal> clause
-attached to a data type declaration.) These <literal>deriving instance</literal>
-rules obey the same rules concerning form and termination as ordinary instance declarations,
-controlled by the same flags; see <xref linkend="instance-decls"/>. </para>
+attached to a data type declaration.)
+
+A <literal>deriving instance</literal> declaration
+must obey the same rules concerning form and termination as ordinary instance declarations,
+controlled by the same flags; see <xref linkend="instance-decls"/>.
+</para>
+<para>
+Unlike a <literal>deriving</literal>
+declaration attached to a <literal>data</literal> declaration, the instance can be more specific
+than the data type (assuming you also use
+<literal>-XFlexibleInstances</literal>, <xref linkend="instance-rules"/>). Consider
+for example
+<programlisting>
+ data Foo a = Bar a | Baz String
+
+ deriving instance Eq a => Eq (Foo [a])
+ deriving instance Eq a => Eq (Foo (Maybe a))
+</programlisting>
+This will generate a derived instance for <literal>(Foo [a])</literal> and <literal>(Foo (Maybe a))</literal>,
+but other types such as <literal>(Foo (Int,Bool))</literal> will not be an instance of <literal>Eq</literal>.
+</para>
<para>The stand-alone syntax is generalised for newtypes in exactly the same
way that ordinary <literal>deriving</literal> clauses are generalised (<xref linkend="newtype-deriving"/>).
These restrictions ensure that context reduction terminates: each reduction
step makes the problem smaller by at least one
constructor. Both the Paterson Conditions and the Coverage Condition are lifted
-if you give the <option>-fallow-undecidable-instances</option>
+if you give the <option>-XUndecidableInstances</option>
flag (<xref linkend="undecidable-instances"/>).
You can find lots of background material about the reason for these
restrictions in the paper <ulink
don't recommend using this approach with GHC.</para>
</sect2>
- <sect2 id="deprecated-pragma">
- <title>DEPRECATED pragma</title>
- <indexterm><primary>DEPRECATED</primary>
- </indexterm>
+ <sect2 id="warning-deprecated-pragma">
+ <title>WARNING and DEPRECATED pragmas</title>
+ <indexterm><primary>WARNING</primary></indexterm>
+ <indexterm><primary>DEPRECATED</primary></indexterm>
- <para>The DEPRECATED pragma lets you specify that a particular
- function, class, or type, is deprecated. There are two
- forms.
+ <para>The WARNING pragma allows you to attach an arbitrary warning
+ to a particular function, class, or type.
+ A DEPRECATED pragma lets you specify that
+ a particular function, class, or type is deprecated.
+ There are two ways of using these pragmas.
<itemizedlist>
<listitem>
- <para>You can deprecate an entire module thus:</para>
+ <para>You can work on an entire module thus:</para>
<programlisting>
module Wibble {-# DEPRECATED "Use Wobble instead" #-} where
...
</programlisting>
+ <para>Or:</para>
+<programlisting>
+ module Wibble {-# WARNING "This is an unstable interface." #-} where
+ ...
+</programlisting>
<para>When you compile any module that import
<literal>Wibble</literal>, GHC will print the specified
message.</para>
</listitem>
<listitem>
- <para>You can deprecate a function, class, type, or data constructor, with the
- following top-level declaration:</para>
+ <para>You can attach a warning to a function, class, type, or data constructor, with the
+ following top-level declarations:</para>
<programlisting>
{-# DEPRECATED f, C, T "Don't use these" #-}
+ {-# WARNING unsafePerformIO "This is unsafe; I hope you know what you're doing" #-}
</programlisting>
<para>When you compile any module that imports and uses any
of the specified entities, GHC will print the specified
message.</para>
- <para> You can only deprecate entities declared at top level in the module
+ <para> You can only attach to entities declared at top level in the module
being compiled, and you can only use unqualified names in the list of
- entities being deprecated. A capitalised name, such as <literal>T</literal>
+ entities. A capitalised name, such as <literal>T</literal>
refers to <emphasis>either</emphasis> the type constructor <literal>T</literal>
<emphasis>or</emphasis> the data constructor <literal>T</literal>, or both if
- both are in scope. If both are in scope, there is currently no way to deprecate
- one without the other (c.f. fixities <xref linkend="infix-tycons"/>).</para>
+ both are in scope. If both are in scope, there is currently no way to
+ specify one without the other (c.f. fixities
+ <xref linkend="infix-tycons"/>).</para>
</listitem>
</itemizedlist>
- Any use of the deprecated item, or of anything from a deprecated
- module, will be flagged with an appropriate message. However,
- deprecations are not reported for
- (a) uses of a deprecated function within its defining module, and
- (b) uses of a deprecated function in an export list.
+ Warnings and deprecations are not reported for
+ (a) uses within the defining module, and
+ (b) uses in an export list.
The latter reduces spurious complaints within a library
in which one module gathers together and re-exports
the exports of several others.
</para>
<para>You can suppress the warnings with the flag
- <option>-fno-warn-deprecations</option>.</para>
+ <option>-fno-warn-warnings-deprecations</option>.</para>
</sect2>
<sect2 id="inline-noinline-pragma">
<programlisting>
key_function :: Int -> String -> (Bool, Double)
-
-#ifdef __GLASGOW_HASKELL__
{-# INLINE key_function #-}
-#endif
</programlisting>
- <para>(You don't need to do the C pre-processor carry-on
- unless you're going to stick the code through HBC—it
- doesn't like <literal>INLINE</literal> pragmas.)</para>
-
<para>The major effect of an <literal>INLINE</literal> pragma
is to declare a function's “cost” to be very low.
The normal unfolding machinery will then be very keen to
All of these effects are aimed at ensuring that what gets inlined is
exactly what you asked for, no more and no less.
</para>
+<para>GHC ensures that inlining cannot go on forever: every mutually-recursive
+group is cut by one or more <emphasis>loop breakers</emphasis> that is never inlined
+(see <ulink url="http://research.microsoft.com/%7Esimonpj/Papers/inlining/index.htm">
+Secrets of the GHC inliner, JFP 12(4) July 2002</ulink>).
+GHC tries not to select a function with an INLINE pragma as a loop breaker, but
+when there is no choice even an INLINE function can be selected, in which case
+the INLINE pragma is ignored.
+For example, for a self-recursive function, the loop breaker can only be the function
+itself, so an INLINE pragma is always ignored.</para>
+
<para>Syntactically, an <literal>INLINE</literal> pragma for a
function can be put anywhere its type signature could be
put.</para>
<literal>UniqueSupply</literal> monad code, we have:</para>
<programlisting>
-#ifdef __GLASGOW_HASKELL__
{-# INLINE thenUs #-}
{-# INLINE returnUs #-}
-#endif
</programlisting>
<para>See also the <literal>NOINLINE</literal> pragma (<xref
linkend="noinline-pragma"/>).</para>
+
+ <para>Note: the HBC compiler doesn't like <literal>INLINE</literal> pragmas,
+ so if you want your code to be HBC-compatible you'll have to surround
+ the pragma with C pre-processor directives
+ <literal>#ifdef __GLASGOW_HASKELL__</literal>...<literal>#endif</literal>.</para>
+
</sect3>
<sect3 id="noinline-pragma">
#-}
</programlisting>
</para>
+<para>
+Use the debug flag <option>-ddump-simpl-stats</option> to see what rules fired.
+If you need more information, then <option>-ddump-rule-firings</option> shows you
+each individual rule firing in detail.
+</para>
<sect2>
<title>Syntax</title>
terminating. For example:
<programlisting>
- "loop" forall x,y. f x y = f y x
+ "loop" forall x y. f x y = f y x
</programlisting>
This rule will cause the compiler to go into an infinite loop.
<listitem>
<para>
- In the earlier phases of compilation, GHC inlines <emphasis>nothing
-that appears on the LHS of a rule</emphasis>, because once you have substituted
-for something you can't match against it (given the simple minded
-matching). So if you write the rule
-
+Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected
+results. Consider this (artificial) example
<programlisting>
- "map/map" forall f,g. map f . map g = map (f.g)
-</programlisting>
+f x = x
+{-# RULES "f" f True = False #-}
-this <emphasis>won't</emphasis> match the expression <literal>map f (map g xs)</literal>.
-It will only match something written with explicit use of ".".
-Well, not quite. It <emphasis>will</emphasis> match the expression
+g y = f y
-<programlisting>
-wibble f g xs
+h z = g True
</programlisting>
-
-where <function>wibble</function> is defined:
-
+Since <literal>f</literal>'s right-hand side is small, it is inlined into <literal>g</literal>,
+to give
<programlisting>
-wibble f g = map f . map g
+g y = y
</programlisting>
-
-because <function>wibble</function> will be inlined (it's small).
-
-Later on in compilation, GHC starts inlining even things on the
-LHS of rules, but still leaves the rules enabled. This inlining
-policy is controlled by the per-simplification-pass flag <option>-finline-phase</option><emphasis>n</emphasis>.
-
+Now <literal>g</literal> is inlined into <literal>h</literal>, but <literal>f</literal>'s RULE has
+no chance to fire.
+If instead GHC had first inlined <literal>g</literal> into <literal>h</literal> then there
+would have been a better chance that <literal>f</literal>'s RULE might fire.
+</para>
+<para>
+The way to get predictable behaviour is to use a NOINLINE
+pragma on <literal>f</literal>, to ensure
+that it is not inlined until its RULEs have had a chance to fire.
</para>
</listitem>
<listitem>