Overlapping instance declarations

Serge D. Mechveliani mechvel at botik.ru
Fri Sep 19 11:01:41 EDT 2008


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.



More information about the Glasgow-haskell-users mailing list