</title>
<para> The recursive do-notation (also known as mdo-notation) is implemented as described in
-"A recursive do for Haskell",
-Levent Erkok, John Launchbury",
+<ulink url="http://citeseer.ist.psu.edu/erk02recursive.html">A recursive do for Haskell</ulink>,
+by Levent Erkok, John Launchbury,
Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania.
+This paper is essential reading for anyone making non-trivial use of mdo-notation,
+and we do not repeat it here.
</para>
<para>
The do-notation of Haskell does not allow <emphasis>recursive bindings</emphasis>,
</programlisting>
<para>
The function <literal>mfix</literal>
-dictates how the required recursion operation should be performed. If recursive bindings are required for a monad,
-then that monad must be declared an instance of the <literal>MonadFix</literal> class.
-For details, see the above mentioned reference.
+dictates how the required recursion operation should be performed. For example,
+<literal>justOnes</literal> desugars as follows:
+<programlisting>
+justOnes = mfix (\xs' -> do { xs <- Just (1:xs'); return xs }
+</programlisting>
+For full details of the way in which mdo is typechecked and desugared, see
+the paper <ulink url="http://citeseer.ist.psu.edu/erk02recursive.html">A recursive do for Haskell</ulink>.
+In particular, GHC implements the segmentation technique described in Section 3.2 of the paper.
</para>
<para>
+If recursive bindings are required for a monad,
+then that monad must be declared an instance of the <literal>MonadFix</literal> class.
The following instances of <literal>MonadFix</literal> are automatically provided: List, Maybe, IO.
Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy modules provide the instances of the MonadFix class
for Haskell's internal state monad (strict and lazy, respectively).
(If you add the flag <option>-XIncoherentInstances</option>,
GHC will instead pick (C), without complaining about
the problem of subsequent instantiations.)
-
+</para>
+<para>
Notice that we gave a type signature to <literal>f</literal>, so GHC had to
<emphasis>check</emphasis> that <literal>f</literal> has the specified type.
Suppose instead we do not give a type signature, asking GHC to <emphasis>infer</emphasis>
<sect1 id="special-ids">
<title>Special built-in functions</title>
-<para>GHC has a few built-in funcions with special behaviour,
-described in this section. All are exported by
-<literal>GHC.Exts</literal>.</para>
-
-<sect2> <title>The <literal>seq</literal> function </title>
-<para>
-The function <literal>seq</literal> is as described in the Haskell98 Report.
-<programlisting>
- seq :: a -> b -> b
-</programlisting>
-It evaluates its first argument to head normal form, and then returns its
-second argument as the result. The reason that it is documented here is
-that, despite <literal>seq</literal>'s polymorphism, its
-second argument can have an unboxed type, or
-can be an unboxed tuple; for example <literal>(seq x 4#)</literal>
-or <literal>(seq x (# p,q #))</literal>. This requires <literal>b</literal>
-to be instantiated to an unboxed type, which is not usually allowed.
-</para>
-</sect2>
-
-<sect2> <title>The <literal>inline</literal> function </title>
-<para>
-The <literal>inline</literal> function is somewhat experimental.
-<programlisting>
- inline :: a -> a
-</programlisting>
-The call <literal>(inline f)</literal> arranges that <literal>f</literal>
-is inlined, regardless of its size. More precisely, the call
-<literal>(inline f)</literal> rewrites to the right-hand side of <literal>f</literal>'s
-definition.
-This allows the programmer to control inlining from
-a particular <emphasis>call site</emphasis>
-rather than the <emphasis>definition site</emphasis> of the function
-(c.f. <literal>INLINE</literal> pragmas <xref linkend="inline-noinline-pragma"/>).
-</para>
-<para>
-This inlining occurs regardless of the argument to the call
-or the size of <literal>f</literal>'s definition; it is unconditional.
-The main caveat is that <literal>f</literal>'s definition must be
-visible to the compiler. That is, <literal>f</literal> must be
-let-bound in the current scope.
-If no inlining takes place, the <literal>inline</literal> function
-expands to the identity function in Phase zero; so its use imposes
-no overhead.</para>
-
-<para> If the function is defined in another
-module, GHC only exposes its inlining in the interface file if the
-function is sufficiently small that it <emphasis>might</emphasis> be
-inlined by the automatic mechanism. There is currently no way to tell
-GHC to expose arbitrarily-large functions in the interface file. (This
-shortcoming is something that could be fixed, with some kind of pragma.)
-</para>
-</sect2>
-
-<sect2> <title>The <literal>lazy</literal> function </title>
-<para>
-The <literal>lazy</literal> function restrains strictness analysis a little:
-<programlisting>
- lazy :: a -> a
-</programlisting>
-The call <literal>(lazy e)</literal> means the same as <literal>e</literal>,
-but <literal>lazy</literal> has a magical property so far as strictness
-analysis is concerned: it is lazy in its first argument,
-even though its semantics is strict. After strictness analysis has run,
-calls to <literal>lazy</literal> are inlined to be the identity function.
-</para>
-<para>
-This behaviour is occasionally useful when controlling evaluation order.
-Notably, <literal>lazy</literal> is used in the library definition of
-<literal>Control.Parallel.par</literal>:
-<programlisting>
- par :: a -> b -> b
- par x y = case (par# x) of { _ -> lazy y }
-</programlisting>
-If <literal>lazy</literal> were not lazy, <literal>par</literal> would
-look strict in <literal>y</literal> which would defeat the whole
-purpose of <literal>par</literal>.
-</para>
-<para>
-Like <literal>seq</literal>, the argument of <literal>lazy</literal> can have
-an unboxed type.
-</para>
-
-</sect2>
-
-<sect2> <title>The <literal>unsafeCoerce#</literal> function </title>
-<para>
-The function <literal>unsafeCoerce#</literal> allows you to side-step the
-typechecker entirely. It has type
-<programlisting>
- unsafeCoerce# :: a -> b
-</programlisting>
-That is, it allows you to coerce any type into any other type. If you use this
-function, you had better get it right, otherwise segmentation faults await.
-It is generally used when you want to write a program that you know is
-well-typed, but where Haskell's type system is not expressive enough to prove
-that it is well typed.
-</para>
-<para>
-The argument to <literal>unsafeCoerce#</literal> can have unboxed types,
-although extremely bad things will happen if you coerce a boxed type
-to an unboxed type.
-</para>
-
-</sect2>
-
+<para>GHC has a few built-in funcions with special behaviour. These
+are now described in the module <ulink
+url="../libraries/base/GHC-Prim.html"><literal>GHC.Prim</literal></ulink>
+in the library documentation.</para>
</sect1>