When Mark Shields and I tackled this problem we came up with
Object-Oriented Style Overloading for Haskell
http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm
It describes an (unimplemented) extension to Haskell, rather than
modelling it in Haskell itself, but you may find it interesting none the
less.
Simon
| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org[mailto:haskell-cafe-bounces at haskell.org] On Behalf Of
| Brandon Michael Moore
| Sent: 24 September 2003 22:22
| To: haskell-cafe at haskell.org| Subject: Modeling multiple inheritance
|| 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
|| _______________________________________________
| Haskell-Cafe mailing list
|Haskell-Cafe at haskell.org|http://www.haskell.org/mailman/listinfo/haskell-cafe