Commit d9f43665 authored by Joachim Breitner's avatar Joachim Breitner Committed by thoughtpolice
Browse files

Improve documentation of the new IncoherentInstances behaviour


Signed-off-by: thoughtpolice's avatarAustin Seipp <aseipp@pobox.com>
parent 099f9542
......@@ -381,17 +381,16 @@ data OverlapFlag
-- its ambiguous which to choose)
| OverlapOk { isSafeOverlap :: Bool }
-- | Silently ignore this instance if you
-- find any other that matches the constraing you
-- are trying to resolve, including when checking if there are instances that
-- do not match, but unify.
-- | Silently ignore this instance if you find any other that matches the
-- constraing you are trying to resolve, including when checking if there are
-- instances that do not match, but unify.
--
-- Example: constraint (Foo [b])
-- instances (Foo [Int]) Incoherent
-- (Foo [a])
-- Without the Incoherent flag, we'd complain that
-- instantiating 'b' would change which instance
-- was chosen.
-- was chosen. See also note [Incoherent instances]
| Incoherent { isSafeOverlap :: Bool }
deriving (Eq, Data, Typeable)
......
......@@ -625,7 +625,7 @@ insert_overlapping new_item (item:items)
-- Keep new one
| old_beats_new = item : items
-- Keep old one
| incoherent new_item = item : items -- note [Incoherent Instances]
| incoherent new_item = item : items -- note [Incoherent instances]
-- Keep old one
| incoherent item = new_item : items
-- Keep new one
......@@ -653,18 +653,34 @@ insert_overlapping new_item (item:items)
_ -> True
\end{code}
Note [Incoherent Instances]
Note [Incoherent instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The original motivation for incoherent instances was about the situation where
an instance would unify, but not match. That would be an error, unless the
unifying instances is marked as incoherent. Example:
For some classes, the choise of a particular instance does not matter, any one
is good. E.g. consider
class D a b where { opD :: a -> b -> String }
instance D Int b where ...
instance D a Int where ...
g (x::Int) = opD x x
For such classes this should work (without having to add an "instance D Int
Int", and using -XOverlappingInstances, which would then work). This is what
-XIncoherentInstances is for: Telling GHC "I don't care which instance you use;
if you can use one, use it."
Should this logic only work when all candidates have the incoherent flag, or
even when all but one have it? The right choice is the latter, which can be
justified by comparing the behaviour with how -XIncoherentInstances worked when
it was only about the unify-check (note [Overlapping instances]):
Example:
class C a b c where foo :: (a,b,c)
instance C [a] b Int
instance [incoherent] [Int] b c
instance [incoherent] C a Int c
Thanks to the incoherent flags,
foo :: ([a],b,Int)
works: Only instance one matches, the others just unify, but are marked
......@@ -675,13 +691,12 @@ So I can write
but if that works then I really want to be able to write
foo :: ([Int], Int, Int)
as well. Now all three instances from above match. None is more specific than
another, so none is ruled out by the normal overlapping rules. In order to
allow this, we now (Aug 2013) liberarate the meaning of Incoherent instances to
say: "An incoherent instances can be ignored if there is another matching
instances." This subsumes the ignore-incoheren-unify-logic.
another, so none is ruled out by the normal overlapping rules. One of them is
not incoherent, but we still want this to compile. Hence the
"all-but-one-logic".
The implementation is in insert_overlapping, where we remove incoherent
instances if there are others.
The implementation is in insert_overlapping, where we remove matching
incoherent instances as long as there are are others.
......
......@@ -4505,21 +4505,33 @@ and <option>-XIncoherentInstances</option>
<indexterm><primary>-XIncoherentInstances
</primary></indexterm>, as this section discusses. Both these
flags are dynamic flags, and can be set on a per-module basis, using
an <literal>OPTIONS_GHC</literal> pragma if desired (<xref linkend="source-file-options"/>).</para>
an <literal>LANGUAGE</literal> pragma if desired (<xref linkend="language-pragma"/>).</para>
<para>
The <option>-XOverlappingInstances</option> flag instructs GHC to loosen
the instance resolution described in <xref linkend="instance-resolution"/>, by
allowing more than one instance to match, <emphasis>provided there is a most specific one</emphasis>.
allowing more than one instance to match, <emphasis>provided there is a most
specific one</emphasis>. The <option>-XIncoherentInstances</option> flag
further loosens the resolution, by allowing more than one instance to match,
irespective of whether there is a most specific one.
</para>
<para>
For example, consider
<programlisting>
instance context1 => C Int a where ... -- (A)
instance context1 => C Int b where ... -- (A)
instance context2 => C a Bool where ... -- (B)
instance context3 => C Int [a] where ... -- (C)
instance context3 => C a [b] where ... -- (C)
instance context4 => C Int [Int] where ... -- (D)
</programlisting>
The constraint <literal>C Int [Int]</literal> matches instances (A),
(C) and (D), but the last is more specific, and hence is chosen. If there is no
most-specific match, the program is rejected.
compiled with <option>-XOverlappingInstances</option> enabled. The constraint
<literal>C Int [Int]</literal> matches instances (A), (C) and (D), but the last
is more specific, and hence is chosen.
</para>
<para>If (D) did not exist then (A) and (C) would still be matched, but neither is
most specific. In that case, the program would be rejected even with
<option>-XOverlappingInstances</option>. With
<option>-XIncoherentInstances</option> enabled, it would be accepted and (A) or
(C) would be chosen arbitrarily.
</para>
<para>
An instance declaration is <emphasis>more specific</emphasis> than another iff
......@@ -4534,17 +4546,15 @@ However, GHC is conservative about committing to an overlapping instance. For e
f x = ...
</programlisting>
Suppose that from the RHS of <literal>f</literal> we get the constraint
<literal>C Int [b]</literal>. But
<literal>C b [b]</literal>. But
GHC does not commit to instance (C), because in a particular
call of <literal>f</literal>, <literal>b</literal> might be instantiate
to <literal>Int</literal>, in which case instance (D) would be more specific still.
So GHC rejects the program.</para>
<para>
If, however, you add the flag <option>-XIncoherentInstances</option>,
GHC will instead pick (C), without complaining about
the problem of subsequent instantiations. In general, the flag
<option>-XIncoherentInstances</option> will cause GHC to ignore an instance if
there is another instance that matches the constraint.
If, however, you add the flag <option>-XIncoherentInstances</option> when
compiling the module that contians (D), 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
......@@ -4554,7 +4564,7 @@ it instead. In this case, GHC will refrain from
simplifying the constraint <literal>C Int [b]</literal> (for the same reason
as before) but, rather than rejecting the program, it will infer the type
<programlisting>
f :: C Int [b] => [b] -> [b]
f :: C b [b] => [b] -> [b]
</programlisting>
That postpones the question of which instance to pick to the
call site for <literal>f</literal>
......@@ -4652,6 +4662,10 @@ some other constraint. But if the instance declaration was compiled with
<option>-XIncoherentInstances</option>, GHC will skip the "does-it-unify?"
check for that declaration.
</para></listitem>
<listitem><para>
If two instance declarations are matched and either is compiled with
<option>-XIncoherentInstances</option>, then that declaration is ignored.
</para></listitem>
</itemizedlist>
These rules make it possible for a library author to design a library that relies on
overlapping instances without the library client having to know.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment