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