[Haskell] Dynamic binding
Lennart Augustsson
lennart at augustsson.net
Thu Jun 23 16:55:31 EDT 2005
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: 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
>
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
>
More information about the Haskell
mailing list