Yes, a) is a weakness, but usually I don't find it too restrictive.
I agree that extensible data types would be a very interesting
addition to Haskell, and I'd like to have it.

But the original question was how to do it in Haskell, and when I
hear Haskell i think Haskell-98 since it's the only standardized
version of Haskell.  So I tried to answer the question.
I wish Haskell-98 had existentials, but people didn't dare in
those days. :)  (Even though hbc had it implemented.)

        -- Lennart


Ralf Lammel wrote:
Lennart,

from a textbook perspective I agree
that this solution should be mentioned to make it easy
for non-Haskellers to get into the subject.

However (as you of course know, but I just don't understand
why you don't dare to mention the limitations a) and b) ...)

a)

Your constructor-based approach is not extensible.
(Adding another form of shape requires touching existing code and
recompilation.) I reckon that the (normal implied OO) point of
the Shapes example, to a considerable extent, is also about the
potential addition of new shapes.

Saying we can take a snapshot of shape "types"  and burn them
into constructors of an algebraic type does not give me the
impression of Haskell being ahead in type system and programming
language arena.

b)

This "burn subtypes into constructors" leads me to a second
weakness. By doing so, we have lost the precision of the
original type dichotomy circle vs rectangle vs square since
these guys are now all represented as terms of type.

Of course, you might say that we could define dedicated
types for circle, rectangle and square so that we would use
the shape type merely as a *sum* type. (So constructors
only serve for embedding.) This way we could at least recover
the typing precision of OO.

So I am willing to give in on b) but I maintain a) and I really miss extensible datatypes :-)

Ralf
(doing too much C# these days I guess)



-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]

On

Behalf Of Lennart Augustsson
Sent: Thursday, June 23, 2005 7:30 AM
To: Andrew Ward
Cc: haskell@haskell.org
Subject: Re: [Haskell] Dynamic binding

Andrew Ward wrote:

Hi All,
In Simon Thompson's The Craft of Functional Programming Second

Edition,

page 226, it is mentioned that Laufer (1996) describes a Haskell
extension to allow dynamic binding. I was wondering if this has been
implemented as an extension in any of the haskell compilers, or

variants?

I am a c++ programmer by trade, only dabbling in Haskell when I was

at

university, so it seems a disadvantage to me to not have dynamic

binding

in Haskell 98.
What would be the normal way for a Haskell programmer to handle the
typical shape example in beginner OO tutorials?


Unlike previous posters that have shown various ways to simulate
object oriented programming I'm going to try and answer the
question. :)

Here is what I would do:

----------------------
data Shape
        = Circle Point Radius
        | Square Point Size

draw :: Shape -> Pict
draw (Circle p r) = drawCircle p r
draw (Square p s) = drawRectangle p s s

moveTo :: Shape -> Point -> Shape
moveTo (Circle _ r) p = Circle p r
moveTo (Square _ s) p = Square p s

shapes :: [Shape]
shapes = [Circle (0,0) 1, Square (1,1) 2]

shapes' :: [Shape]
shapes' = map (moveTo (2,2)) shapes
----------------------

This is in rather stark contrast to the object oriented way of doing

the

same things.  For reference, here's how you could do it :

----------------------
class IsShape shape where
    draw :: shape -> Pict
    moveTo :: Point -> shape -> shape

data Shape = forall a . (IsShape a) => Shape a

data Circle = Circle Point Radius
instance IsShape Circle where
    draw (Circle p r) = drawCircle p r
    moveTo p (Circle _ r) = Circle p r

data Square = Square Point Size
instance IsShape Square where
    draw (Square p s) = drawRectangle p s s
    moveTo p (Square _ s) = Square p s

shapes :: [Shape]
shapes = [Shape (Circle (0,0) 10), Shape (Square (1,1) 2)]

shapes' :: [Shape]
shapes' = map (moveShapeTo (2,2)) shapes
  where moveShapeTo p (Shape s) = Shape (moveTo p s)
----------------------

Both ways of doing it contains the same information, it's just that
it's organized in different ways.

The "functional way" centers around the type Shape.  You can find out
all about what shapes exist by looking at the type definition.  For
each operation on shapes (draw & moveTo) you describe what they do for
the different shapes.

The object oriented way centers more around the objects (surprise,
surprise).  For each kind of object you say that it's a shape and how
the shape operations work.


So, which is better?  I don't think you can say one is better than the
other.  They have different strengths.  With the object oriented way

it

is easy to answer questions like "What is a Circle?", whereas with the
functional way it is easy to answer "How do you draw a Shape"?
Likewise, with the object oriented way it's easier to add a new kind
of shape and with the functional way it's easier to add a new
operation.

To me it's a matter of taste.  I like the functional taste; my brain
has been warped over many years.

        -- Lennart
_______________________________________________
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


_______________________________________________
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell

Reply via email to