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
>to 
>
>   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 
functions.

>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