[Haskell] Dynamic binding

Ralf Lammel ralfla at microsoft.com
Thu Jun 23 03:52:39 EDT 2005


Andrew,

you are circumventing the hard problem!

(Even though I am sure you just forgot to mention it.)

That is, the question is about drawing a *list* of shapes.

As correctly observed by Rathman ages back, one naturally
ends up with existential quantification when simulating
dynamic binding. Ex. quantification is sufficiently scary
for folks moving from C++ to Haskell. But fortunately it's
not necessary ... see earlier plug ...

Ralf



> -----Original Message-----
> From: haskell-bounces at haskell.org [mailto:haskell-bounces at haskell.org]
On
> Behalf Of ajb at spamcop.net
> Sent: Thursday, June 23, 2005 12:42 AM
> To: haskell at haskell.org
> Subject: Re: Re[2]: [Haskell] Dynamic binding
> 
> 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.
> 
> Cheers,
> Andrew Bromage
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell


More information about the Haskell mailing list