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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On > Behalf Of [EMAIL PROTECTED] > Sent: Thursday, June 23, 2005 12:42 AM > To: [email protected] > 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 > [email protected] > http://www.haskell.org/mailman/listinfo/haskell _______________________________________________ Haskell mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell
