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: haskell-bounces at haskell.org [mailto:haskell-bounces at haskell.org]
On
> Behalf Of Lennart Augustsson
> Sent: Thursday, June 23, 2005 7:30 AM
> To: Andrew Ward
> Cc: haskell at 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 at haskell.org>http://www.haskell.org/mailman/listinfo/haskell