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