O'Haskell OOP Polymorphic Functions

Ashley Yakeley ashley@semantic.org
Tue, 16 Jan 2001 00:54:17 -0800

At 2001-01-16 00:03, Johan Nordlander wrote:

>Ashley Yakeley wrote:
>> How do you do OOP-style polymorphic functions in O'Haskell? My first
>> attempt looked something like this:
>> struct Base
>> struct Derived < Base =
>>      value :: Int
>> theValue :: Base -> Maybe Int
>> theValue x = Just (x.value) -- problem line
>> theValue _ = Nothing
>> In the problem line, x is considered to be of type Base, so x.value 
>> gives an error. 
>I'm not sure what OOP-style you're referring to.  This is like trying
>to access the "color" field of an ordinary, uncolored "point".

Right, but returning 'Nothing' for uncolored points and (Just) the color 
for colored points.

> How would you program your function in Java?

Library code:

public class Base

public class Derived
extends Base
     public int value;

     public Derived(int v)
          value = v;

Application code:

     public static MaybeInt theValue(Base x)
          if (x instanceof Derived)
           return new MaybeInt(((Derived) x).value);
          else return MaybeInt.NOTHING;

>> I tried replacing it with
>> theValue (x :: Derived) = Just (x.value)
>> ...but that doesn't work either.
>But that's just because O'Haskell doesn't support type annotated
>variables in patterns (yet).  Change the type signature of your function
>   theValue :: Derived -> Maybe Int
>instead, and it should typecheck (it still wouldn't make much sense, though).

I want a function of type 'Base -> Maybe Int' that returns the value of a 
Derived and Nothing for any other Base.

Is it possible to construct such a function?

>However, as a general remark, I'd like to point out that record terms in
>O'Haskell don't carry their type with them at run-time.  Like in C++,
>the type of a record term is a purely static notion that only exists at
>compile time.  Hence it's not possible to define a function that returns
>a value that depends on the dynamic type of its argument (a big win when
>one wants to enforce information hiding).
>The solution is instead to use an ordinary datatype for values that one
>would like to scrutinize at run-time by pattern-matching (the FP way),

This requires knowing the entire type structure before defining any such 

>or to internalize the function in question into the record type itself
>(the OOP way).

This requires knowing all such functions before defining the type 
structure. It also makes multiple dispatch difficult. I'm not sure this 
can even be done by adding a dynamic-type field, since you still need to 
cast to the Derived type to get the value.

Ashley Yakeley, Seattle WA