Leon Smith wrote: [snip]
If GHC had true existential typing, as opposed to just existential datatypes, you could reasonably code what I think you want like this:
class A a where basicA :: Bool nextA :: a -> (EX a'. A a' => a') basicA = True nextA = id
data WrappedA = forall a. A a => WrappedA a
instance A WrappedA where basicA = False nextA (WrappedA a) = a
data A1 = A1
instance A A1
--... similarly for B ...
class AB a b where toBool :: a -> b -> Bool
instance (A a, B b) => AB a b where toBool a b | (basicA :: a) && (basicB :: b) = True | (basicA :: a) || (basicB :: b) = False | otherwise = toBool (nextA a) (nextB b) [snip] Either I've missed something, or this isn't what I wanted. The problem I have is that AB is not extensible. If you want to add a new instances A2,B2 of A,B and a new definition of toBool which just works for A2 and B2, you can't do it, without changing the definition of toBool in the above instance.