
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@haskell.org] On Behalf Of Joachim Breitner | Sent: 19 August 2013 09:07 | To: glasgow-haskell-users@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@joachim-breitner.de • http://www.joachim-breitner.de/ | Jabber: nomeata@joachim-breitner.de • GPG-Key: 0x4743206C | Debian Developer: nomeata@debian.org