[Haskell-cafe] Query regarding Type classes

Arun Suresh arun.suresh at gmail.com
Mon Oct 13 06:50:27 EDT 2008


On Mon, Oct 13, 2008 at 4:08 PM, Ryan Ingram <ryani.spam at gmail.com> wrote:

> On Mon, Oct 13, 2008 at 11:18 AM, Arun Suresh <arun.suresh at gmail.com>
> wrote:
> ] you seem to have read my mind [:)].. i actaually hit upon this issue
> while
> ] trying to "transcode" some C++ to Haskell..
>
> (literate haskell post, save it into "draw.lhs" and you can load it in
> ghci!)
>
> What you usually want when you have some "closed world" OO class
> hierarchy is to replace the hierarchy with an ADT.
>
> For example:
>
> class Drawable {
>    virtual void render() = 0;
> }
>
> class Rectangle : public Drawable
> {
>    Rectangle(Point corner1, Point corner2);
>    ...
> }
>
> class Circle : public Drawable
> {
>    Circle(Point center, float radius);
>    ...
> }
>
> turns into
>
> > data Point = Pt { x :: Float, y :: Float } deriving Show
> > data Drawable = Rectangle Point Point | Circle Point Float
>

I agree that this does look more succinct... but what if I write some
generic code for the
in the render method of the Drawable class and package it into a library..

Now my client want to write another subclass for Drawable...
He can do that in any other file... package.. whatever...

How would he do that in Haskell ???
considering he may not modify the source file in while i have defined the
Drawable ADT..

I know it is possible using Type Classes... Have a Drawable Type Class..
etc.. etc..
Is there probably a better way of dooing it ??



> > render :: Drawable -> IO ()
> > render (Rectangle p1 p2) = putStrLn (concat ["Rectangle from ", show p1,
> " to ", show p2, "."])
> > render (Circle center radius) = putStrLn (concat ["Circle at ", show
> center, " with radius ", show radius, "."])
>
> This inverts the control from the OO structure; in the OO the
> interface is centralized and the data is spread throughout the source.
>  In the pattern-matching style, the data is centralized (in the ADT)
> but the interface can be spread out.
>
> For example, to add a new function "area()" to Drawable, in the OO
> style you have to add it to Drawable and put an implementation into
> every class that descends from Drawable, modifying all those modules.
> But in Haskell you could declare a new function in one place:
>
> > area :: Drawable -> Float
> > area (Rectangle p1 p2) = abs (x p2 - x p1) * abs (y p2 - y p1)
> > area (Circle _ r) = pi * r * r
>
> On the other hand, adding new data to Rectangle or Circle requires
> changing all the pattern matches spread throughout the source, which
> is somewhat annoying.  So there are benefits of both styles.
>
> It's possible to emulate the OO style in Haskell, using existential
> types, but it is a lot harder.  It's easier to stick with what the
> language is good at! :)


Hmmm... I suspect this answers the question I stated above...

>
>
>  -- ryan


-Arun
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20081013/163d11ae/attachment-0001.htm


More information about the Haskell-Cafe mailing list