Jan-Willem Maessen wrote:
On Jun 22, 2005, at 9:38 PM, Andrew Ward wrote:
Pal-Kristian Engstad wrote:
On Wednesday 22 June 2005 05:38 pm, Andrew Ward wrote:
What would be the normal way for a Haskell programmer to handle the
typical shape example in beginner OO tutorials?
By not doing OO. You have to ask yourself, what is the purpose
and/or benefit of using OO? In C++, OO is _useful_ because you
restrict the problems of mutable data (by enclosing it in C++ classes).
ML type languages have other methods of doing things, and guess
what, OO is not that needed for these languages. Sum-types,
pattern-matching and data constructors make half of the need for OO
go away. Higher order functions and make it even less needed. For
the rest, there's always work-arounds.
PKE.
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<shape *> shapes;
for(std::list<shape *>::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.
It seems to me that if this is the specific problem being addressed, a
list of higher-order functions is exactly the right solution in any
ML-like language, and this is why there have been several responses to
that effect.
I do think it's fair to say "consider changing the way you think" to
OO programmers trying to learn Haskell. If we were on an OOP mailing
list, I could ask for days how to simulate pattern matching and
algebraic types---and get a nonsensical runaround involving the
visitor pattern and huge swaths of unreadable code.
Ralf, I think it's incumbent on you, having said several times "that
isn't solving the problem", to more clearly explain what problem you
think exists and cannot be solved gracefully (I suspect it has to do
with extensible down-casting---which is indeed hard in Haskell, but
many reasonable people might consider irrelevant or even overtly bad).
Andrew, if this isn't the problem you're actually trying to solve, can
you explain why a simple list of functions doesn't help you?
I think I will need to learn a little more Haskell before I can
appreciate all the different responses. However I will try to answer
your question.
Assuming I have a list of shapes somewhere in my program. The list would
be heterogeneous, or at least contain data constructed using various
different type constructors. The list would also be changing all the
time, for example in a drawing program. So, using the suggestion of a
list of drawing functions, would this not mean I would have to alter the
list of drawing functions each time I alter the list of shapes? It does
not seem an extensible solution. When it comes to adding new types or
new functionality for existing types would it not be easy to miss
updating a part of the program source that needed updating?
The example I have found the simplest is the one given by Lennart,
however this to me seems equivalent to the way people use switch
statements in C to mimic dynamic binding.
As I said before, I will have to learn more haskell and investigate
OOHaskell properly.
Thanks for all your responses.
-Jan-Willem Maessen
Andrew Ward.
_______________________________________________
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe