Modeling multiple inheritance

Brandon Michael Moore brandon at its.caltech.edu
Wed Sep 24 15:22:18 EDT 2003


I'm trying to build a nicer interface over the one generated by
jvm-bridge. I'm using fancy type classes to remove the need to mangle
method names. I would like methods to be automatcially inherited,
following an inheritance hierarcy defined with another set of type
classes.

My basic classes look like this
class HasFooMethod cls args result | cls args -> result where
  foo :: cls -> args -> result

If I have classes A and B with foo methods like
  foo_JA_Jint :: ClassA -> Jint -> Bool
  foo_JB_Jboolean :: ClassB -> Bool -> Jint
then I can make instances
  instance HasFooMethod ClassA Jint Bool
  instance HasFooMethod ClassB Bool Jint

Now I can just use foo everywhere. I would like to avoid declaring an
instance for every class though. In java methods are inherited from a
superclass, and I would like to inherit methods automatically as well. In
the bindings jvm-bridge generates a method is invoked with a function
mangled after the highest ancestor that defined that particular
overloading, so the implementation of HasFooMethod at a particular
overloading is the same for any descendant.

So I defined a class to model the inheritance relationships

class SubType super sub | sub -> super where
  upCast :: sub -> super

Now I can define a default instance of HasFooMethod:
instance (HasFooMethod super args result,
          SubClass super sub) =>
         HasFooMethod sub args result where
  foo sub args = foo (upCast sub) args

This will propagate foo methods down the inheritance hierarcy. If a new
class C is derived from A, I just need to say

instance SubClass ClassA ClassC

and ClassC gets a foo method. (In the actually code I piggy-back on a
transitive subclass relation jvm-bridge defines that already includes an
upcast method, so upCast has a default that should always be acceptable).

The problem comes when interfaces are added to the mix. Interfaces are
treated just like classes by jvm-bridge, and even though no implementation
is inherited from instances in Java, the method accessors generated by
jvm-bridge should be inherited.

One problem is that the subclass relationship needs the functional
dependency so that the default instance of HasFooMethod will respects the
functional dependencies of HasFooMethod, so I can't declare subclass
instances for multiple inheritance. On the other hand, if I don't use the
functional dependency on HasFooMethod I end up needing to annotate most of
the return values in a program. I run into similar problems trying to use
numeric literals as arguments, because they are also overloaded.

Does anyone know of clever solutions that would model multiple inheritance
while preserving the functional dependencies (unsafe compiler flags are
fine too), or ways to reduce the pain of overloading resolution without
the functional dependency?

One alternative is generating seperate HasFooMethod instances for every
class in the system. The problem is that this would require alterating the
bit of jvm-bridge that uses JNI to find information on classes, which
currently only reports newly defined methods. JNI is black magic to me.

Thanks
Brandon



More information about the Haskell-Cafe mailing list