incoherent instance selection when it should be still coherent

The following pain is sort of ghc (6.4.2) specific. (The same behavior is achievable with hugs -98 +O which is Ok in so far that +O (as opposed to +o) is not strongly supposed to be coherent.) Note the following GHC options preceding the code. They do not contain -fallow-incoherent-instances. {-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-overlapping-instances #-} -- A single parameter class with two silly instances class Foo x where foo :: x -> (); foo = const () instance Foo () instance Foo Bool -- A two-parameter class with a generic and a non-generic instance class (Foo x, Foo y) => Bar x y where bar :: x -> y -> String instance (Foo x, Foo y) => Bar x y where bar _ _ = "generic instance" instance Foo z => Bar () z where bar _ _ = "non-generic instance" -- An existential wrapper around foos data Wrap = forall x. Foo x => Wrap x -- A wrapper-based variation on the type-class member bar uuh :: Wrap -> Wrap -> String uuh (Wrap x) (Wrap y) = bar x y -- Let's try all unwrapped and wrapped combinations of bar and uuh t1 = () t2 = True w1 = Wrap t1 w2 = Wrap t2 main = do print $ bar t1 t1 print $ uuh w1 w1 -- uuh! print $ bar t1 t2 print $ uuh w1 w2 -- uuh! print $ bar t2 t1 print $ uuh w2 w1 print $ bar t2 t2 print $ uuh w2 w2 We get: {- "non-generic instance" "generic instance" "non-generic instance" "generic instance" "generic instance" "generic instance" "generic instance" "generic instance" -} This means that the generic instance is consistently chosen by uuh. This is clearly incoherent. I would also complain that uuh type-checks in the first place. Opinions? Regards, Ralf
participants (1)
-
Ralf Lammel