overlapping instances in 7.10.1
Sergei Meshveliani
mechvel at botik.ru
Sun Jun 14 15:56:20 UTC 2015
On Sat, 2015-06-13 at 23:07 +0000, Simon Peyton Jones wrote:
(I reformat this text a bit)
> [..]
> I finally found time to look into what is happening here. It’s a good
> illustration of the dangers of overlapping instances. Here is the
> setup:
>
>
> * Module ResEuc_
>
> * Contains
> instance (...) => Ring (ResidueE a) <---- (A)
> instance (..., Ring (ResidueE a)) => Field (ResidueE a) <---- (B)
>
>
> * Module PFact__
>
> * Imports Pgcd_, which imports ResEuc_
>
> * Contains code that needs
>
> (Field (ResidueE (UPol (ResidueE Integer)))) <------ (X)
>
> * To solve (X) we use instance (B) from ResEuc_
> * And hence we need to solve
> (Ring (ResidueE (UPol (ResidueE Integer))))
>
> which we do using (A) but not (C)
>
>
> * Module RsePol_
>
> * Imports PFact__
> * Contains the specialised instance
>
> instance (...) => Ring (ResidueE (UPol a)) <------ (C)
>
> which overlaps instance (A)
>
> * Module Main
> * Needs an instance for
>
> Field (ResidueE (UPol (Residue Integer))) <------ (Y)
>
> * Although GHC *could* generate this by instance declarations,
> which it would do using (B) and then using (C),
>
> instead GHC cleverly sees that it has generated it before,
> in module PFact__, and so uses the one from PFact__.
> And that is what gives rise to your error
>
>
> So the real problem is that in PFact__, we make an instance (X) that
> does not see the specialised instance (C).
> It *cannot* see that instance because RsePol_ imports PFact__.
(is is called Pfact__).
Yes, I intended this. And this is not a problem. This is because Pfact_
uses somewhat a smaller knowledge library than there may use further
modules which import Pfact_.
> So whatever code uses (X) is not going to see the specialised
> instance.
Why?
ghc-7.8.3 treats overlapping instances differently.
My intention was (and is) as follows.
Compiling Main, the compiler sees the two solutions for (Y):
the one imported from Pfact__ -- which implementation (dictionary?) is
ready,
and another that can be generated using (C) from RsePol_.
By the meaning of what are overlapping instances, the compiler must
resolve between these two. And this is resolved by the rule of checking
the substitutional instance between instances.
`Main' imports more knowledge about instances than Pfact_ does, so it is
supposed to use an additional knowledge.
The fact that one of the overlapping instances is already generated must
not be a sufficient reason to set it in Main.
This is why I think that ghc-7.8.3 treats the OI notion in a more
natural way than ghc-7.10.1 does.
May be, ghc-7.10.1 has a better technical tool for this, but ghc-7.8.3
corresponds to a natural notion of OI.
Can GHC return to a natural OI notion?
Or am I missing something?
> I bet that this is not what you intend. This may be a latent bug in
> DoCon.
If I am not missing anything in my above discourse, then DoCon is all
right at this point.
> I solved the problem by combining PFact__ and RsePol_ into a single
> module. Then everything works fine.
I think that this approach will generally lead to great difficulties in
composing an application.
Please, consider my above explanation and tell me whether I am missing
something.
Regards,
------
Sergei
> What are the general lessons here?
>
> GHC generally assumes that if it generates (C T) in one place,
> then it can use that anywhere in the program that (C T) is needed.
> That is, there is only one (C T) dictionary.
>
>
> · But suppose you have overlapping instance in different
> modules; say
>
> module A where instance C [a]
>
> module B where import A; instance C [Maybe a]
>
> If you use (C [Maybe Int]) in A, then of course we won’t see the
> instance in B. So you’ll get a different dictionary than if you
> compute C [Maybe Int] in module B.
>
>
>
> In short, overlapping instances are OK, but it’s best to put them in
> the same module as the instances they overlap.
>
>
>
> Could GHC behave as if all instances were calculated afresh in the
> module being compiled. Yes, of course it could, but at the cost of
> losing the benefit of cross-module specialisation. An overloaded
> function specialised at, say, [Int] in one module could not be re-used
> in another in case the instances changed.
>
>
>
> Simon
>
>
> | -----Original Message-----
> | From: ghc-tickets [mailto:ghc-tickets-bounces at haskell.org] On Behalf
> Of
> | Sergei Meshveliani
> | Sent: 23 May 2015 22:08
> | To: glasgow-haskell-users at haskell.org
> | Cc: glasgow-haskell-bugs at haskell.org
> | Subject: overlapping instances in 7.10.1
> | Dear GHC developers,
> |
> | This request overrides my previous one of "7.10.1-err..."
> | (it is simpler and more precise).
> | The archive
> | http://www.botik.ru/pub/local/Mechveliani/ghcQuest/7.10.1-errReport-
> | may23-2015.zip
> |
> | presents a question about ghc-7.10.1.
>
> | Make it, please, with ghc-7.10.1 by
> | ghc $doconCpOpt -O --make Main
> | ,
> | $doconCpOpt =
> | -fwarn-unused-matches -fwarn-unused-binds -fwarn-unused-imports
> | -fno-warn-overlapping-patterns -XRecordWildCards -XNamedFieldPuns
> | -XFlexibleContexts -XMultiParamTypeClasses -XUndecidableInstances
> | -XTypeSynonymInstances -XFlexibleInstances -fcontext-stack=30
>
> |
> | as it is written there in README.txt.
> | README.txt explains which two instances are wrongly resolved
> | -- as I expect.
> | In ghc-7.8.2 they are resolved in a correct way
> | (and there is a different pragma syntax).
> | I conclude this from running the test in docon-2.12.
> | Am I missing something?
> | Please, advise,
> | ------
> | Sergei
More information about the Glasgow-haskell-users
mailing list