which contains a module <literal>A</literal>, say, it generates
an object <filename>A.o</filename>, <emphasis>and</emphasis> a
companion <emphasis>interface file</emphasis>
- <filename>A.hi</filename>. The interface file is not intended
- for human consumption, as you'll see if you take a look at one.
- It's merely there to help the compiler compile other modules in
- the same program.</para>
-
+ <filename>A.hi</filename>. The interface file is merely there
+ to help the compiler compile other modules in the same program.
+ Interfaces are in a binary format, so don't try to look at one;
+ however you <emphasis>can</emphasis> see the contents of an
+ interface file by using GHC with the
+ <option>--show-iface</option> option (see <xref
+ linkend="hi-options">, below).</para>
+
<para>NOTE: In general, the name of a file containing module
<literal>M</literal> should be named <filename>M.hs</filename>
or <literal>M.lhs</literal>. The only exception to this rule is
</sect2>
+ <sect2 id="finding-hierarchical-modules">
+ <title>Finding interfaces for hierarchical modules</title>
+
+ <para>GHC supports a hierarchical module namespace as an
+ extension to Haskell 98 (see <xref
+ linkend="hierarchical-modules">).</para>
+
+ <para>A module name in general consists of a sequence of
+ components separated by dots
+ (‘<literal>.</literal>’). When looking for
+ interface files for a hierarchical module, the compiler turns
+ the dots into path separators, so for example a module
+ <literal>A.B.C</literal> becomes <literal>A/B/C</literal> (or
+ <literal>A\B\C</literal> under Windows). Then each component of
+ the import directories list is tested in turn; so for example if
+ the list contains directories
+ <literal>D<subscript>1</subscript></literal> to
+ <literal>D<subscript>n</subscript></literal>, then the compiler
+ will look for the interface in
+ <literal>D<subscript>1</subscript>/A/B/C.hi</literal> first,
+ then <literal>D<subscript>2</subscript>/A/B/C.hi</literal> and
+ so on.</para>
+
+ <para>Note that it's perfectly reasonable to have a module which
+ is both a leaf and a branch of the tree. For example, if we
+ have modules <literal>A.B</literal> and
+ <literal>A.B.C</literal>, then <literal>A.B</literal>'s
+ interface file will be in <literal>A/B.hi</literal> and
+ <literal>A.B.C</literal>'s interface file will be in
+ <literal>A/B/C.hi</literal>.</para>
+
+ <para>For GHCi and <option>--make</option>, the search strategy
+ for source files is exactly the same, just replace the
+ <literal>.hi</literal> suffix in the above description with
+ <literal>.hs</literal> or <literal>.lhs</literal>.</para>
+ </sect2>
+
<Sect2 id="hi-options">
<title>Other options related to interface files</title>
<indexterm><primary>interface files, options</primary></indexterm>
<variablelist>
<varlistentry>
- <term><option>-ohi</option> <replaceable>file</replaceable></term>
- <indexterm><primary><option>-ohi</option></primary>
- </indexterm>
- <listitem>
- <para>The interface output may be directed to another file
- <filename>bar2/Wurble.iface</filename> with the option
- <option>-ohi bar2/Wurble.iface</option> (not recommended).
- To avoid generating an interface at all, you can say
- <literal>-ohi /dev/null</literal>, for example.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
<term><option>-ddump-hi</option></term>
<indexterm><primary><option>-ddump-hi</option></primary>
</indexterm>
the labour.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>--show-iface</option>
+ <replaceable>file</replaceable></term>
+ <indexterm><primary><option>--show-iface</option></primary>
+ </indexterm>
+ <listitem>
+ <para>Where <replaceable>file</replaceable> is the name of
+ an interface file, dumps the contents of that interface in
+ a human-readable (ish) format.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
-
+
</sect2>
<sect2 id="recomp">
.SUFFIXES : .o .hs .hi .lhs .hc .s
cool_pgm : $(OBJS)
- rm $@
+ rm -f $@
$(HC) -o $@ $(HC_OPTS) $(OBJS)
# Standard suffix rules
<filename>makefile</filename>, then the old dependencies are
deleted first.</para>
+ <para>Don't forget to use the same <option>-package</option>
+ options on the <literal>ghc -M</literal> command line as you
+ would when compiling; this enables the dependency generator to
+ locate any imported modules that come from packages. The
+ package modules won't be included in the dependencies
+ generated, though (but see the
+ <option>––include-prelude</option> option below).</para>
+
<para>The dependency generation phase of GHC can take some
additional options, which you may find useful. For historical
reasons, each option passed to the dependency generator from
</varlistentry>
<varlistentry>
- <term><option>--exclude-module=<file></option></term>
+ <term><option>––exclude-module=<file></option></term>
<listitem>
<para>Regard <filename><file></filename> as
"stable"; i.e., exclude it from having dependencies on
<varlistentry>
<term><option>-x</option></term>
<listitem>
- <para>same as <option>--exclude-module</option></para>
+ <para>same as <option>––exclude-module</option></para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--exclude-directory=<dirs></option></term>
+ <term><option>––exclude-directory=<dirs></option></term>
<listitem>
<para>Regard the colon-separated list of directories
<filename><dirs></filename> as containing stable,
</varlistentry>
<varlistentry>
- <term><option>--include-module=<file></option></term>
+ <term><option>––include-module=<file></option></term>
<listitem>
<para>Regard <filename><file></filename> as not
"stable"; i.e., generate dependencies on it (if
any). This option is normally used in conjunction with
- the <option>--exclude-directory</option> option.</para>
+ the <option>––exclude-directory</option> option.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--include-prelude</option></term>
+ <term><option>––include-prelude</option></term>
<listitem>
- <para>Regard prelude libraries as unstable, i.e.,
- generate dependencies on the prelude modules used
- (including <literal>Prelude</literal>). This option is
- normally only used by the various system libraries. If a
- <option>-package</option> option is used, dependencies
- will also be generated on the library's
- interfaces.</para>
+ <para>Regard modules imported from packages as unstable,
+ i.e., generate dependencies on the package modules used
+ (including <literal>Prelude</literal>, and all other
+ standard Haskell libraries). This option is normally
+ only used by the various system libraries.</para>
</listitem>
</varlistentry>
</variablelist>
would look like the following:</para>
<ProgramListing>
-__interface A 1 0 where
-__export A TA{MkTA} ;
-1 newtype TA = MkTA PrelBase.Int ;
+module A where
+newtype TA = MkTA GHC.Base.Int
</ProgramListing>
- <para>The syntax is essentially the same as a normal
- <filename>.hi</filename> file (unfortunately), so you can
- usually tailor an existing <filename>.hi</filename> file to make
- a <filename>.hi-boot</filename> file.</para>
+ <para>The syntax is similar to a normal Haskell source file, but
+ with some important differences:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Non-local entities must be qualified with their
+ <emphasis>original</emphasis> defining module. Qualifying
+ by a module which just re-exports the entity won't do. In
+ particular, most <literal>Prelude</literal> entities aren't
+ actually defined in the <literal>Prelude</literal> (see for
+ example <literal>GHC.Base.Int</literal> in the above
+ example). HINT: to find out the fully-qualified name for
+ entities in the <literal>Prelude</literal> (or anywhere for
+ that matter), try using GHCi's
+ <literal>:info</literal> command, eg.</para>
+<programlisting>Prelude> :m -Prelude
+> :i IO.IO
+-- GHC.IOBase.IO is a type constructor
+newtype GHC.IOBase.IO a
+...</programlisting>
+ </listitem>
+ <listitem>
+ <para>Only <literal>data</literal>, <literal>type</literal>,
+ <literal>newtype</literal>, <literal>class</literal>, and
+ type signature declarations may be included. You cannot declare
+ <literal>instances</literal> or derive them automatically.
+</para>
+ </listitem>
+ </itemizedlist>
<para>Notice that we only put the declaration for the newtype
<literal>TA</literal> in the <literal>hi-boot</literal> file,
not the signature for <Function>f</Function>, since
<Function>f</Function> isn't used by <literal>B</literal>.</para>
- <para>The number “1” after
- “__interface A” gives the version
- number of module A; it is incremented whenever anything in A's
- interface file changes. In a normal interface file, the
- “0” is the version number of the compiler which
- generated the interface file; it is used to ensure that we don't
- mix-and-match interface files between compiler versions.
- Leaving it as zero in an <literal>hi-boot</literal> file turns
- off this check.</para>
-
- <para>The number “1” at the beginning of a
- declaration is the <emphasis>version number</emphasis> of that
- declaration: for the purposes of <filename>.hi-boot</filename>
- files these can all be set to 1. All names must be fully
- qualified with the <emphasis>original</emphasis> module that an
- object comes from: for example, the reference to
- <literal>Int</literal> in the interface for <literal>A</literal>
- comes from <literal>PrelBase</literal>, which is a module
- internal to GHC's prelude. It's a pain, but that's the way it
- is.</para>
-
<para>If you want an <literal>hi-boot</literal> file to export a
data type, but you don't want to give its constructors (because
the constructors aren't used by the SOURCE-importing module),
you can write simply:</para>
<ProgramListing>
-__interface A 1 0 where
-__export A TA;
-1 data TA
+module A where
+data TA
</ProgramListing>
<para>(You must write all the type parameters, but leave out the
'=' and everything that follows it.)</para>
-
- <para><emphasis>Note:</emphasis> This is all a temporary
- solution, a version of the compiler that handles mutually
- recursive modules properly without the manual construction of
- interface files, is (allegedly) in the works.</para>
</sect2>
wasted work, but there is no avoiding it. You should therefore do
your best to have as few orphan modules as possible.
-</para><para>
-You can identify an orphan module by looking in its interface file, M.hi. If there is a ``!'' on
-the first line, GHC considers it an orphan module.
+</para>
+
+<para> You can identify an orphan module by looking in its interface
+file, <filename>M.hi</filename>, using the
+<option>--show-iface</option>. If there is a ``!'' on the first line,
+GHC considers it an orphan module.
</para>
</sect2>