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.de • http://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