Liberalising IncoherentInstances

Simon Peyton-Jones simonpj at microsoft.com
Mon Aug 19 10:27:39 CEST 2013


Yes that makes sense to me.  Please do document the reasoning of this thread (and the example you give) in a "Note [Incoherent instances]" somewhere though!

S

| -----Original Message-----
| From: Glasgow-haskell-users [mailto:glasgow-haskell-users-
| bounces at haskell.org] On Behalf Of Joachim Breitner
| Sent: 19 August 2013 09:07
| To: glasgow-haskell-users at haskell.org
| Subject: Re: Liberalising IncoherentInstances
| 
| Good morning,
| 
| Am Samstag, den 27.07.2013, 20:16 +0000 schrieb Simon Peyton-Jones:
| > So the change I propose to make IncoherentInstances to pick
| > arbitrarily among instances that match.  More precisely, when trying
| > to find an instance matching a target constraint (C tys),
| >
| > a) Find all instances matching (C tys); these are the candidates
| >
| > b) Eliminate any candidate X for which another candidate Y is
| >   strictly more specific (ie Y is a substitution instance of X),
| >   if either X or Y was complied with -XOverlappingInstances
| >
| > c) Check that any non-candidate instances that *unify* with (C tys)
| >    were compiled with -XIncoherentInstances
| >
| > d) If only one candidate remains, pick it.
| >     Otherwise if all remaining candidates were compiled with
| >     -XInccoherentInstances, pick an arbitrary candidate
| >
| > All of this is precisely as now, except for the "Otherwise" part of
| > (d).  One could imagine different flags for the test in (c) and (d)
| > but I really don't think it's worth it.
| 
| I believe it would be more consistent to change the otherwise part of
| (d) to “Otherwise, if all but at most one remaining candidates were
| compiled with -XInccoherentInstances, pick the one that does not have
| the flag, or any other”. The rationale is that it goes much better with
| (c):
| 
| Consider a typical example for (c):
| 
|         class C a b where foo :: (a,b)
|         instance C [a] b
|         instance [incoherent] [Int] b
|         instance [incoherent] C a Int
| 
| now
|         foo :: ([a],b])
| works (only one instance matches, the others unify, but are incoherent.
| So I can write
|         (foo :: ([a],b])) :: ([Int], Int]).
| But I cannot write
|         foo :: ([Int], Int])
| as now all three instances from above match. The second is ruled out in
| step (b), but the third is not, so we are in case (d) and by the
| original logic, things fail here.
| 
| If we allow one non-incoherent instance (and, for consistency with (b),
| pick that), it would work.
| 
| I’ll prepare the patch in that variant, but of course I’ll change it if
| it turns out I am wrong here.
| 
| Greetings,
| Joachim
| 
| 
| 
| 
| --
| Joachim “nomeata” Breitner
|   mail at joachim-breitner.dehttp://www.joachim-breitner.de/
|   Jabber: nomeata at joachim-breitner.de  • GPG-Key: 0x4743206C
|   Debian Developer: nomeata at debian.org


More information about the Glasgow-haskell-users mailing list