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