Multi-parameter OOP

George Russell
Fri, 19 Oct 2001 17:02:54 +0200

Recently I've been experimenting with a sort of OOP with GHC, using existential types and
(overlapping, undecidable) multi-parameter type classes, but it doesn't seem to work as you 
might expect because of the way GHC resolves overloaded functions at compile-time.  For example, 
given class A a

data WrappedA = forall a . A a => WrappedA a
data A1 = A1 
instance A A1

class B b
data WrappedB = forall b . B b => WrappedB b
data B1 = B1 
instance B B1

class AB a b where
   toBool :: a -> b -> Bool
instance (A a,B b) => AB a b where
   toBool _ _ = False
instance AB A1 B1 where
   toBool _ _ = True

instance AB WrappedA WrappedB where
   toBool (WrappedA a) (WrappedB b) = toBool a b

a naive user (like me a month ago) might expect that this to work, so that
toBool (WrappedA a) (WrappedB b) will return False unless a is an A1, and b a B1,
in which case it returns True.  In fact ghc5.02 (rightly) gives an error message
with the second instance declaration:
Could not unambiguously deduce (AB a b) from the context (A a, B b)
    The choice of (overlapping) instance declaration
        depends on the instantiation of `a, b'

So is there any other way of doing this sort of dynamic lookup at runtime, in
a reasonably neat way?