[Haskell] Dynamic binding

ajb at spamcop.net ajb at spamcop.net
Thu Jun 23 03:42:22 EDT 2005

G'day all.

Thursday, June 23, 2005, 5:38:03 AM, you wrote:

> To handle the problem of drawing all shapes, in c++, I would have a list
> of shape pointers:

> struct shape{ virtual void draw(...);};
> struct circle : public shape {...};
> struct square : public shape {...};
> std::list<shape *> shapes;
> for(std::list<shape *>::iterator it = shapes.begin();it !=
> shapes.end();++it)
> { (*it)->>draw(...); }

> This general pattern of dynamic binding I use over and over again. Could
> you give me some example code of this type of thing handled in Haskell's
> way? Assuming that the number of classes deriving from shape might get
> quite large.

class Drawable s where
    draw :: s -> IO ()

data Circle = Circle Point Radius

instance Drawable Circle where
    draw (Circle centre radius) = ...

If you only need interface inheritance, this should do.  If you also need
implementation inheritance, then you can model it with an upcast method:

data Shape = Shape Stuff

class Shape s where
    toShape :: s -> Shape
    draw :: s -> IO ()

instance Shape Shape where
    toShape s = s
    draw s = ...

data Circle = Circle Shape Point Radius

instance Shape Circle where
    toShape (Circle s _ _) = s
    draw (Circle _ centre radius) = ...

In your original example, draw() wasn't abstract virtual, so I assume
there's a reasonable default draw() method for your "shape" class.  If
there isn't, then it's probably better in Haskell to split the typeclass:

class Shape s where
    toShape :: s -> Shape

class (Shape s) => DrawableShape s where
    draw :: s -> IO ()

And only define DrawableShape on types where "draw" makes sense.

Andrew Bromage

More information about the Haskell mailing list