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
participants (1)
-
Ashley Yakeley