RE: Re[2]: [Haskell] Dynamic binding

2005-06-23 Thread Ralf Lammel
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: haskell@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 shapes;
> > for(std::list::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@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: Re[2]: [Haskell] Dynamic binding

2005-06-23 Thread ajb
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 shapes;
> for(std::list::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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


RE: Re[2]: [Haskell] Dynamic binding

2005-06-23 Thread Ralf Lammel
Bulat,

Bulat wrote:

> just create list of draw functions itself:
> 
> [drawCircle (10,10) 5, drawSquare (20,20) 10]

No! the exercise is about lists of shapes
not lists of results of drawing shapes.
This is clearly a major difference.


Bulat wrote:

> for more complex tasks - declare interface as a structure:
> 
> data ShapeInterface = Shape { draw :: IO (),
>   moveTo :: Point -> IO (),
>   calcArea :: Float
> }

No! You miss the point that the different shapes
differ regarding state types.
You don't have a chance when you use one datatype.

haskell-cafe?

Ralf

> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On
> Behalf Of Bulat Ziganshin
> Sent: Thursday, June 23, 2005 12:18 AM
> To: Andrew Ward
> Cc: Pal-Kristian Engstad; haskell@haskell.org
> Subject: Re[2]: [Haskell] Dynamic binding
> 
> Hello Andrew,
> 
> Thursday, June 23, 2005, 5:38:03 AM, you wrote:
> 
> AW> To handle the problem of drawing all shapes, in c++, I would have
a
> list
> AW> of shape pointers:
> 
> AW> struct shape{ virtual void draw(...);};
> AW> struct circle : public shape {...};
> AW> struct square : public shape {...};
> AW> std::list shapes;
> AW> for(std::list::iterator it = shapes.begin();it !=
> AW> shapes.end();++it)
> { (*it)->>draw(...); }
> 
> AW> This general pattern of dynamic binding I use over and over again.
> Could
> AW> you give me some example code of this type of thing handled in
> Haskell's
> AW> way? Assuming that the number of classes deriving from shape might
get
> AW> quite large.
> 
> just create list of draw functions itself:
> 
> [drawCircle (10,10) 5, drawSquare (20,20) 10]
> 
> you are not expected that this problem can be solved with one line of
> code? :)
> 
> 
> for more complex tasks - declare interface as a structure:
> 
> data ShapeInterface = Shape { draw :: IO (),
>   moveTo :: Point -> IO (),
>   calcArea :: Float
> }
> 
> 
> and return this structures from "constructor" functions:
> 
> circle x y r = Shape { draw = drawCircle center r,
>moveTo newCenter = ,
>calcArea = pi*r*r
>  }
>where center = Point x y
> 
> square x y size = Shape { draw = ,
>   moveTo newCenter = ,
>   calcArea = size*szie
> }
> 
> figures = [circle 1 2 3, square 4 5 6, circle 7 8 9]
> 
> 
> 
> of course, you cannot use inherited field names when using this
> technique :)
> 
> --
> Best regards,
>  Bulatmailto:[EMAIL PROTECTED]
> 
> 
> 
> ___
> Haskell mailing list
> Haskell@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell