[Haskell-cafe] Functional dependencies and incoherent instances

Ryan Ingram ryani.spam at gmail.com
Wed Oct 8 12:58:23 EDT 2008

On Wed, Oct 8, 2008 at 2:59 PM, Tobias Bexelius
<tobias.bexelius at avalanchestudios.se> wrote:
> Or do I have too much faith in the -fallow-incoherent-instances flag now? :/

Overlapping instances are an "instance definition"-time feature;
incoherent instances only become applicable at the call site for
polymorphic functions in the presence of overlapping instances.

As an example, consider the following overlapping instances:

{-# LANGUAGE OverlappingInstances #-}

class Foo a where foo :: a -> Bool

instance Foo a where
  foo x = False

instance Foo Integer where
  foo x = (x == 3)

test1 :: String -> Bool
test1 x = foo x  -- uses "Foo a" instance

test2 :: Integer -> Bool
test2 x = foo x -- uses "Foo Integer" instance

test3 :: a -> Bool
test3 x = foo x -- incoherent!

Consider (test3 (3 :: Integer)).  This should definitely use the
implementation for instance Foo Integer.  But it can't, because test3
doesn't know what type its argument is!

Incoherent instances still allows test3 to compile, but it may choose
the "wrong" instance.  In this case, test3 will use the "Foo a"
instance no matter what type of argument you pass it.

But the incoherency only arises at a call-site for the class method;
if you take test3 out of this program, the instances are still
overlapping but there is no compile problem (assuming
-foverlapping-instances).  If you are getting an error because of an
instance definition, as opposed to a call site, incoherent instances
won't help you.

  -- ryan

More information about the Haskell-Cafe mailing list