<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>
</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>
<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#</literal>s
+ will store two unboxed <literal>Int#</literal>s
directly in the <function>T</function> constructor. The
unpacker can see through newtypes, too.</para>
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 ======================== -->