[Haskell-cafe] incoherent instance selection when it should be
still coherent
Ralf Lammel
Ralf.Lammel at microsoft.com
Fri Jul 21 20:36:45 EDT 2006
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
More information about the Haskell-Cafe
mailing list