Query regarding GHC handling of overlapping instances.

Simon Peyton-Jones simonpj at microsoft.com
Tue Sep 16 18:39:18 EDT 2003


| If I change the definition to:
| 
|     instance Test (a -> m b) z where
|         test _ _ = "Third"
| 
| it now complains about it overlapping with both of the other
| definitions... Why does this overlap?

Here are your instance decls

	instance Test (a b) (c b) where 
	  test x y = "First"
	instance Test (a b) (a b) where
	  test x y = "Second"
	instance Test (a -> m b) z where
	  test _ _ = "Third"

Two instances *overlap* if there is a constraint (Test t1 t2) that is
	a) (Test t1 t2) is an instance of more than one instance decl
	b) None of these instance decls is more specific than all the
others
Under these circumstances, we can't pick one over the other.

For example, 
	Test (Int -> [Bool]) [Bool]
matches the first instance decl
	a = (->) Int, b = Bool, c = []
and the third
	a = Int, m = [], b = Bool, z = [Bool]

But it is not the case that the first instance decl is more specific
than the third, or vice versa.  (An instance decl I1 is more specific
than I2 if any constraint matching I1 also matches I2).


| If I add the following definition to the test code:
| 
|     instance Test (a -> m b) (m b) where
|         test _ _ = "Third"
| 
| then I add the following print:
| 
|     print $ test (\_ -> [True]) [True]
| 
| it says no instance for (t -> [Bool), but if I add a type annotation
all
| is Okay:
| 
|     print $ test ((\_ -> [True]) :: () -> [Bool]) [True]
| 
| Is this expected behavior? 

NO: it's a bug in GHC, which I have just put into SourceForge. 
http://sourceforge.net/tracker/index.php?func=detail&aid=807249&group_id
=8032&atid=108032
It's rather an obscure case, but definitely wrong.  Thanks for showing
it up.

Simon




More information about the Glasgow-haskell-users mailing list