+</sect3>
+
+<sect3><title>SPECIALIZE for imported functions</title>
+
+<para>
+Generally, you can only give a <literal>SPECIALIZE</literal> pragma
+for a function defined in the same module.
+However if a function <literal>f</literal> is given an <literal>INLINABLE</literal>
+pragma at its definition site, then it can subequently be specialised by
+importing modules (see <xref linkend="inlinable-pragma"/>).
+For example
+<programlisting>
+module Map( lookup, blah blah ) where
+ lookup :: Ord key => [(key,a)] -> key -> Maybe a
+ lookup = ...
+ {-# INLINABLE lookup #-}
+
+module Client where
+ import Map( lookup )
+
+ data T = T1 | T2 deriving( Eq, Ord )
+ {-# SPECIALISE lookup :: [(T,a)] -> T -> Maybe a
+</programlisting>
+Here, <literal>lookup</literal> is declared <literal>INLINABLE</literal>, but
+it cannot be specialised for type <literal>T</literal> at its definition site,
+because that type does not exist yet. Instead a client module can define <literal>T</literal>
+and then specialise <literal>lookup</literal> at that type.
+</para>
+<para>
+Moreover, every module that imports <literal>Client</literal> (or imports a module
+that imports <literal>Client</literal>, transitively) will "see", and make use of,
+the specialised version of <literal>lookup</literal>. You don't need to put
+a <literal>SPECIALIZE</literal> pragma in every module.
+</para>
+<para>
+Moreover you often don't even need the <literal>SPECIALIZE</literal> pragma in the
+first place. When compiling a module M,
+GHC's optimiser (with -O) automatically considers each top-level
+overloaded function declared in M, and specialises it
+for the different types at which it is called in M. The optimiser
+<emphasis>also</emphasis> considers each <emphasis>imported</emphasis>
+<literal>INLINABLE</literal> overloaded function, and specialises it
+for the different types at which it is called in M.
+So in our example, it would be enough for <literal>lookup</literal> to
+be called at type <literal>T</literal>:
+<programlisting>
+module Client where
+ import Map( lookup )
+
+ data T = T1 | T2 deriving( Eq, Ord )
+
+ findT1 :: [(T,a)] -> Maybe a
+ findT1 m = lookup m T1 -- A call of lookup at type T
+</programlisting>
+However, sometimes there are no such calls, in which case the
+pragma can be useful.
+</para>
+</sect3>
+
+<sect3><title>Obselete SPECIALIZE syntax</title>