[Haskell-cafe] Query regarding Type classes

Ryan Ingram ryani.spam at gmail.com
Mon Oct 13 06:38:48 EDT 2008


On Mon, Oct 13, 2008 at 11:18 AM, Arun Suresh <arun.suresh at gmail.com> wrote:
] you seem to have read my mind [:)].. i actaually hit upon this issue while
] trying to "transcode" some C++ to Haskell..

(literate haskell post, save it into "draw.lhs" and you can load it in ghci!)

What you usually want when you have some "closed world" OO class
hierarchy is to replace the hierarchy with an ADT.

For example:

class Drawable {
    virtual void render() = 0;
}

class Rectangle : public Drawable
{
    Rectangle(Point corner1, Point corner2);
    ...
}

class Circle : public Drawable
{
    Circle(Point center, float radius);
    ...
}

turns into

> data Point = Pt { x :: Float, y :: Float } deriving Show
> data Drawable = Rectangle Point Point | Circle Point Float

> render :: Drawable -> IO ()
> render (Rectangle p1 p2) = putStrLn (concat ["Rectangle from ", show p1, " to ", show p2, "."])
> render (Circle center radius) = putStrLn (concat ["Circle at ", show center, " with radius ", show radius, "."])

This inverts the control from the OO structure; in the OO the
interface is centralized and the data is spread throughout the source.
 In the pattern-matching style, the data is centralized (in the ADT)
but the interface can be spread out.

For example, to add a new function "area()" to Drawable, in the OO
style you have to add it to Drawable and put an implementation into
every class that descends from Drawable, modifying all those modules.
But in Haskell you could declare a new function in one place:

> area :: Drawable -> Float
> area (Rectangle p1 p2) = abs (x p2 - x p1) * abs (y p2 - y p1)
> area (Circle _ r) = pi * r * r

On the other hand, adding new data to Rectangle or Circle requires
changing all the pattern matches spread throughout the source, which
is somewhat annoying.  So there are benefits of both styles.

It's possible to emulate the OO style in Haskell, using existential
types, but it is a lot harder.  It's easier to stick with what the
language is good at! :)

  -- ryan


More information about the Haskell-Cafe mailing list