[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