<para>
This section documents GHC's implementation of multi-parameter type
classes. There's lots of background in the paper <ulink
-url="http://research.microsoft.com/~simonpj/multi.ps.gz" >Type
+url="http://research.microsoft.com/~simonpj/Papers/type-class-design-space" >Type
classes: exploring the design space</ulink > (Simon Peyton Jones, Mark
Jones, Erik Meijer).
</para>
instance context3 => C Int [a] where ... -- (C)
instance context4 => C Int [Int] where ... -- (D)
</programlisting>
-The instances (A) and (B) match the constraint <literal>C Int Bool</literal>, but (C) and (D) do not. When matching, GHC takes
+The instances (A) and (B) match the constraint <literal>C Int Bool</literal>,
+but (C) and (D) do not. When matching, GHC takes
no account of the context of the instance declaration
(<literal>context1</literal> etc).
GHC's default behaviour is that <emphasis>exactly one instance must match the
the problem of subsequent instantiations.
</para>
<para>
-Because overlaps are checked and reported lazily, as described above, you need
-the <option>-fallow-overlapping-instances</option> in the module that <emphasis>calls</emphasis>
-the overloaded function, rather than in the module that <emphasis>defines</emphasis> it.</para>
-
+The willingness to be overlapped or incoherent is a property of
+the <emphasis>instance declaration</emphasis> itself, controlled by the
+presence or otherwise of the <option>-fallow-overlapping-instances</option>
+and <option>-fallow-incoherent-instances</option> flags when that mdodule is
+being defined. Neither flag is required in a module that imports and uses the
+instance declaration. Specifically, during the lookup process:
+<itemizedlist>
+<listitem><para>
+An instance declaration is ignored during the lookup process if (a) a more specific
+match is found, and (b) the instance declaration was compiled with
+<option>-fallow-overlapping-instances</option>. The flag setting for the
+more-specific instance does not matter.
+</para></listitem>
+<listitem><para>
+Suppose an instance declaration does not matche the constraint being looked up, but
+does unify with it, so that it might match when the constraint is further
+instantiated. Usually GHC will regard this as a reason for not committing to
+some other constraint. But if the instance declaration was compiled with
+<option>-fallow-incoherent-instances</option>, GHC will skip the "does-it-unify?"
+check for that declaration.
+</para></listitem>
+</itemizedlist>
+All this makes it possible for a library author to design a library that relies on
+overlapping instances without the library client having to know.
+</para>
+<para>The <option>-fallow-incoherent-instances</option> flag implies the
+<option>-fallow-overlapping-instances</option> flag, but not vice versa.
+</para>
</sect3>
<sect3>
</sect2>
+<sect2 id="typing-binds">
+<title>Generalised typing of mutually recursive bindings</title>
+
+<para>
+The Haskell Report specifies that a group of bindings (at top level, or in a
+<literal>let</literal> or <literal>where</literal>) should be sorted into
+strongly-connected components, and then type-checked in dependency order
+(<ulink url="http://haskell.org/onlinereport/decls.html#sect4.5.1">Haskell
+Report, Section 4.5.1</ulink>).
+As each group is type-checked, any binders of the group that
+have
+an explicit type signature are put in the type environment with the specified
+polymorphic type,
+and all others are monomorphic until the group is generalised
+(<ulink url="http://haskell.org/onlinereport/decls.html#sect4.5.2">Haskell Report, Section 4.5.2</ulink>).
+</para>
+
+<para>Following a suggestion of Mark Jones, in his paper
+<ulink url="http://www.cse.ogi.edu/~mpj/thih/">Typing Haskell in
+Haskell</ulink>,
+GHC implements a more general scheme. If <option>-fglasgow-exts</option> is
+specified:
+<emphasis>the dependency analysis ignores references to variables that have an explicit
+type signature</emphasis>.
+As a result of this refined dependency analysis, the dependency groups are smaller, and more bindings will
+typecheck. For example, consider:
+<programlisting>
+ f :: Eq a => a -> Bool
+ f x = (x == x) || g True || g "Yes"
+
+ g y = (y <= y) || f True
+</programlisting>
+This is rejected by Haskell 98, but under Jones's scheme the definition for
+<literal>g</literal> is typechecked first, separately from that for
+<literal>f</literal>,
+because the reference to <literal>f</literal> in <literal>g</literal>'s right
+hand side is ingored by the dependency analysis. Then <literal>g</literal>'s
+type is generalised, to get
+<programlisting>
+ g :: Ord a => a -> Bool
+</programlisting>
+Now, the defintion for <literal>f</literal> is typechecked, with this type for
+<literal>g</literal> in the type environment.
+</para>
+
+<para>
+The same refined dependency analysis also allows the type signatures of
+mutually-recursive functions to have different contexts, something that is illegal in
+Haskell 98 (Section 4.5.2, last sentence). With
+<option>-fglasgow-exts</option>
+GHC only insists that the type signatures of a <emphasis>refined</emphasis> group have identical
+type signatures; in practice this means that only variables bound by the same
+pattern binding must have the same context. For example, this is fine:
+<programlisting>
+ f :: Eq a => a -> Bool
+ f x = (x == x) || g True
+
+ g :: Ord a => a -> Bool
+ g y = (y <= y) || f True
+</programlisting>
+</para>
+</sect2>
</sect1>
<!-- ==================== End of type system extensions ================= -->
</para></listitem>
<listitem><para>
-You cannot use a <literal>deriving</literal> clause on a GADT-style data type declaration,
-nor can you use record syntax. (It's not clear what these constructs would mean. For example,
-the record selectors might ill-typed.) However, you can use strictness annotations, in the obvious places
+You cannot use record syntax on a GADT-style data type declaration. (
+It's not clear what these it would mean. For example,
+the record selectors might ill-typed.)
+However, you can use strictness annotations, in the obvious places
in the constructor type:
<programlisting>
data Term a where
</para></listitem>
<listitem><para>
+You can use a <literal>deriving</literal> clause on a GADT-style data type
+declaration, but only if the data type could also have been declared in
+Haskell-98 syntax. For example, these two declarations are equivalent
+<programlisting>
+ data Maybe1 a where {
+ Nothing1 :: Maybe a ;
+ Just1 :: a -> Maybe a
+ } deriving( Eq, Ord )
+
+ data Maybe2 a = Nothing2 | Just2 a
+ deriving( Eq, Ord )
+</programlisting>
+This simply allows you to declare a vanilla Haskell-98 data type using the
+<literal>where</literal> form without losing the <literal>deriving</literal> clause.
+</para></listitem>
+
+<listitem><para>
Pattern matching causes type refinement. For example, in the right hand side of the equation
<programlisting>
eval :: Term a -> a
<itemizedlist>
<listitem><para> an expression; the spliced expression must have type <literal>Expr</literal></para></listitem>
<listitem><para> a list of top-level declarations; ; the spliced expression must have type <literal>Q [Dec]</literal></para></listitem>
- <listitem><para> a type; the spliced expression must have type <literal>Type</literal>.</para></listitem>
+ <listitem><para> [Planned, but not implemented yet.] a type; the spliced expression must have type <literal>Type</literal>.</para></listitem>
</itemizedlist>
(Note that the syntax for a declaration splice uses "<literal>$</literal>" not "<literal>splice</literal>" as in
the paper. Also the type of the enclosed expression must be <literal>Q [Dec]</literal>, not <literal>[Q Dec]</literal>
the quotation has type <literal>Expr</literal>.</para></listitem>
<listitem><para> <literal>[d| ... |]</literal>, where the "..." is a list of top-level declarations;
the quotation has type <literal>Q [Dec]</literal>.</para></listitem>
- <listitem><para> <literal>[t| ... |]</literal>, where the "..." is a type;
+ <listitem><para> [Planned, but not implemented yet.] <literal>[t| ... |]</literal>, where the "..." is a type;
the quotation has type <literal>Type</literal>.</para></listitem>
</itemizedlist></para></listitem>
</listitem>
<listitem>
- <para>You can deprecate a function, class, or type, with the
+ <para>You can deprecate a function, class, type, or data constructor, with the
following top-level declaration:</para>
<programlisting>
{-# DEPRECATED f, C, T "Don't use these" #-}
<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 depecate 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>
+ 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>
</listitem>
</itemizedlist>
Any use of the deprecated item, or of anything from a deprecated
overloaded function:</para>
<programlisting>
-hammeredLookup :: Ord key => [(key, value)] -> key -> value
+ hammeredLookup :: Ord key => [(key, value)] -> key -> value
</programlisting>
<para>If it is heavily used on lists with
follows:</para>
<programlisting>
-{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
+ {-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
</programlisting>
<para>A <literal>SPECIALIZE</literal> pragma for a function can
(see <xref linkend="rewrite-rules"/>) that rewrites a call to the
un-specialised function into a call to the specialised one.</para>
- <para>In earlier versions of GHC, it was possible to provide your own
+ <para>The type in a SPECIALIZE pragma can be any type that is less
+ polymorphic than the type of the original function. In concrete terms,
+ if the original function is <literal>f</literal> then the pragma
+<programlisting>
+ {-# SPECIALIZE f :: <type> #-}
+</programlisting>
+ is valid if and only if the defintion
+<programlisting>
+ f_spec :: <type>
+ f_spec = f
+</programlisting>
+ is valid. Here are some examples (where we only give the type signature
+ for the original function, not its code):
+<programlisting>
+ f :: Eq a => a -> b -> b
+ {-# SPECIALISE g :: Int -> b -> b #-}
+
+ g :: (Eq a, Ix b) => a -> b -> b
+ {-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-}
+
+ h :: Eq a => a -> a -> a
+ {-# SPECIALISE h :: (Eq a) => [a] -> [a] -> [a] #-}
+</programlisting>
+The last of these examples will generate a
+RULE with a somewhat-complex left-hand side (try it yourself), so it might not fire very
+well. If you use this kind of specialisation, let us know how well it works.
+</para>
+
+ <para>Note: In earlier versions of GHC, it was possible to provide your own
specialised function for a given type:
<programlisting>