
| 2. But in several places DoCon has parasitic additions | (similar to the below MulSemigroup (Fraction a)) | to the context for overlapping instances. | These places are marked in the docon-2.12-pre source with | 'overlaps in ghc'. | I would like to cancel them, similar as we now cancel the above | MulSemigroup (Fraction a) in the context. | But ghc-6.9.20080910 does not allow this. | So, I wonder: what is the difference? No you can't cancel them! Consider class Foo a where fop :: a->a instance Foo [a] where ... instance Foo [Int] where .. class Bar a where bop :: a -> a instance Bar [a] where bop = fop In the Bar [a] instance, we get a constraint (Foo [a]). It's wrong to commit to the Foo [a] instance, because if you are ultimately building a Bar [Int] instance you want the Foo [Int] instance of fop! The Right Thing is to add (Foo [a]) to the context of the Bar instance thus instance Foo [a] => Bar [a] where bop = fop I'll expand the user manual (in the section about overlapping instances) to cover this point. The other situation that DoCon contains is more like this: class C a where { op1,op2 :: a -> a } instance C [Int] where... instance C a => C [a] where op1 x = op2 x ++ op2 x op2 x = ... In the C [a] instance you'll see that op1 calls op2, thereby giving rise to a C [a] constraint. I *originally thought* that the same reasoning applied as above, so we should reject the program. But applying the solution I describe above would give instance C [a], C a => C [a] where .. which is silly. Here the Right Thing is to satisfy the C [a] constraint "locally", without worrying about the overlap. This is justified because we'll only be *in* the code for op1 in the C [a] instance if we know that 'a' does not match Int. Thanks for bringing this up. Simon

Thank you for the explanation. ------ Sergey On Fri, Sep 19, 2008 at 10:26:01AM +0100, Simon Peyton-Jones wrote:
| 2. But in several places DoCon has parasitic additions | (similar to the below MulSemigroup (Fraction a)) | to the context for overlapping instances. | These places are marked in the docon-2.12-pre source with | 'overlaps in ghc'. | I would like to cancel them, similar as we now cancel the above | MulSemigroup (Fraction a) in the context. | But ghc-6.9.20080910 does not allow this. | So, I wonder: what is the difference?
No you can't cancel them! Consider
class Foo a where fop :: a->a instance Foo [a] where ... instance Foo [Int] where ..
class Bar a where bop :: a -> a
instance Bar [a] where bop = fop
In the Bar [a] instance, we get a constraint (Foo [a]). It's wrong to commit to the Foo [a] instance, because if you are ultimately building a Bar [Int] instance you want the Foo [Int] instance of fop!
The Right Thing is to add (Foo [a]) to the context of the Bar instance thus
instance Foo [a] => Bar [a] where bop = fop
I'll expand the user manual (in the section about overlapping instances) to cover this point.
The other situation that DoCon contains is more like this:
class C a where { op1,op2 :: a -> a } instance C [Int] where... instance C a => C [a] where op1 x = op2 x ++ op2 x op2 x = ...
In the C [a] instance you'll see that op1 calls op2, thereby giving rise to a C [a] constraint. I *originally thought* that the same reasoning applied as above, so we should reject the program. But applying the solution I describe above would give
instance C [a], C a => C [a] where ..
which is silly. Here the Right Thing is to satisfy the C [a] constraint "locally", without worrying about the overlap. This is justified because we'll only be *in* the code for op1 in the C [a] instance if we know that 'a' does not match Int.
Thanks for bringing this up.
participants (2)
-
Serge D. Mechveliani
-
Simon Peyton-Jones