
with:
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
class A a class R a
class S a
instance R a => A a instance S a => A a
GHC gives *Duplicate instance declarations* * instance R a => A a * * instance S a => A a * ** *Why?*

Instance instantiation is *not* search, and *not* similar to
subclassing in OO languages.
Both your instance declarations simply add constraints to functions that use it.
Here's a more concrete example:
class A a where
doA :: a -> String
class R a where
doR :: a -> String
instance R Int where doR = show
instance R a => A a where
doA = doR
question x = doA x
The question is, what is the type of "question"? Here are two valid
choices with this program:
question :: (A a) => a -> String
question :: (R a) => a -> String
The instance R a => A a says that every type "a" is an instance of
"A"; if an instance for A is needed, the compiler says "OK, I know how
to make one of those. But I now add a new constraint, R a."
Adding another instance S a => A a makes the choice of what constraint
to add ambiguous. In particular the following code does *not* work:
class S a where
doS :: a -> String
instance S String where
doS = id
instance S a => A a where
doA = doS
question2 = question (2::Int)
question3 = question "3"
In my experience, if you are turning undecidable instances on and you
don't know exactly why it's safe to do so, there is probably a mistake
in your design.
-- ryan
2008/10/24 Alberto G. Corona
with:
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
class A a class R a
class S a
instance R a => A a
instance S a => A a
GHC gives
Duplicate instance declarations instance R a => A a instance S a => A a
Why? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hello Alberto, Friday, October 24, 2008, 12:20:39 PM, you wrote:
instance R a => A a instance S a => A a Duplicate instance declarations Why?
because you may write in other module instance R Int instance S Int if class A includes functions, it may be problematic to determine which implementation (via R or via S) to use -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Fri, Oct 24, 2008 at 10:20:39AM +0200, Alberto G. Corona wrote:
with:
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
class A a class R a
class S a
instance R a => A a instance S a => A a
This point commonly trips people up (it used to trip me up). In addition to what others have said, I hope I can provide a bit more intuition. If you have
instance R a => A a
it *seems* like it should mean, "Any a which is an instance of R is also an instance of A". However, that's *not* what it means! It actually means "Any type which matches 'a' (that is, any type at all) can be an instance of A; and if some type is used as an instance of A, then it must also be an instance of R as well." GHC picks which instance to use by looking *only* at stuff to the right of => in instance declarations. Only after an instance has been chosen is the stuff to the left of the => considered. Hopefully now it is clear why the code above is a duplicate instance declaration; there's no way to distinguish the instances by looking only at stuff to the right of => . -Brent
participants (4)
-
Alberto G. Corona
-
Brent Yorgey
-
Bulat Ziganshin
-
Ryan Ingram