[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