[Haskell] How to avoid both duplicate instances and extraneousinstance declarations?

Claus Reinke claus.reinke at talk21.com
Sat Apr 22 15:51:09 EDT 2006


> I have three classes, A, B1, and B2.  I want all instances of B1 to  
> be instances of A.  I want all instances of B2 to be instances of A.   

if you mean to ensure that an instance of A should be a pre-requisite 
for defining instances of B1/B2, then your second approach might be 
more appropriate. if you mean to ensure that an instance of A is a 
necessary consequence of having an instance for either of B1/B2,
then your first approach seems close, but runs into a technical issue:

by default, an instance of A by means of an instance of B1 may 
differ from an instance of A by means of an instance of B2.

> None of the classes have methods.
> 
> The following does NOT work, because of a duplicate instance  
> declaration for A:
> 
> class A a
> class B1 b1
> class B2 b2
> instance B1 x => A x
> instance B2 x => A x  -- duplicate instance, won't compile
> data T = T
> instance B1 T

the question is: if both B1 x and B2 x hold, does it matter which one 
is chosen in the proof of A x? if it does, how is the implementation to 
choose the right one, and if it doesn't (one might then ask why B1 
and B2 are separate in the first place), how is the implementation
to know that?

you can introduce an arbitrary distinction in the two proofs, and
then throw that distinction away later, as shown below, but whether
or not that works depends on your application context. for instance,
f is accepted and can be applied in either hugs or ghc; but hugs
would complain about the commented out A; ghci would accept
A, and the definition of g, but would complain about any use of g.

cheers,
claus

{-# OPTIONS_GHC -fglasgow-exts #-}
{-# OPTIONS_GHC -fallow-undecidable-instances #-}

class A' a x
-- class A a
-- instance A' a b => A a

data B1T
class B1 b1

data B2T
class B2 b2

instance B1 x => A' x B1T
instance B2 x => A' x B2T -- duplicate instance, won't compile

data T = T
instance B1 T

f :: (forall b . A' x b => x) -> String
f x = undefined

-- g :: A x => x -> String
-- g = undefined



More information about the Haskell mailing list