Haskell doesn't really do inheritance, unless you somehow get O'Haskell to work on a modern machine.
In place of inheritance, you have two mechanisms: algebraic data types and type classes. They work great for many programs, but neither of them is an exact fit for Java-style object-oriented programming.
An algebraic data type has a name ("Bool", in the first example below), and several constructors ("True" and "False"). Constructors can take positional and named arguments, and they can take type parameters:
data Bool = True | False
data Shape =
Square { l :: Int, t :: Int, w :: Int, h :: Int }
| Circle Int Int Int
data Maybe a = Just a | Nothing
Once you define an algebraic data type, you can't add new constructors. But you can write functions which match against the existing constructors at runtime, giving you a form of runtime dispatch vaguely analogous to method lookup:
So algebraic data types work great if you have one abstract interface with known set of concrete subclasses. It's a really great way to think about complex data structures with multiple types of nodes.
A type class is a little bit like a C++ template protocol: It says that a given type implements a set of functions. But as with C++ templates, it's effectively resolved at compile time. (Well, the implementation is quite a bit different, but that's the rough idea.)
Now, ADTs and type classes are great. But if you find yourself using crazy hacks to recreate an OO class hierarchy in Haskell, you're probably fighting against the language. Either structure your program differently, or find a different language.
I agree - type overloading says templates to me rather than inheritance. C++'s tuple class lets you do some of the cool listy type things you can do in Haskell. Using typedef tuple<double, double> FloatPoint and taking it from there seems a lot more like the Haskell example and would be less code - one line each for the typedefs and a one-line function to implement <<. (Not taking anything away from Haskell, which I'm completely in love with.)
The typedef tuple strategy doesn't let you distinguish between types except by the types and ordering of their fields. If you later have a constructor for another ADT (or even the same one) which also takes two Float arguments, you end up with multiple typedefs for tuple<double, double>.
I would say the closest OO analog to ADTs is the Visitor pattern: You first fix the number of classes and then implement the different functions (visitors)
This is in contrast with the normal OO polymorphism/method where you first define set of methods and then implement the different classes.
----------
Type classes are more of a thing of their own. The template comparison is apt and I have heard Type Classes are supposedly very similar to the "Concepts" proposal that did not get in C++0x.
Comments
Haskell doesn't really do inheritance, unless you somehow get O'Haskell to work on a modern machine.
In place of inheritance, you have two mechanisms: algebraic data types and type classes. They work great for many programs, but neither of them is an exact fit for Java-style object-oriented programming.
An algebraic data type has a name ("Bool", in the first example below), and several constructors ("True" and "False"). Constructors can take positional and named arguments, and they can take type parameters:
Once you define an algebraic data type, you can't add new constructors. But you can write functions which match against the existing constructors at runtime, giving you a form of runtime dispatch vaguely analogous to method lookup: So algebraic data types work great if you have one abstract interface with known set of concrete subclasses. It's a really great way to think about complex data structures with multiple types of nodes.A type class is a little bit like a C++ template protocol: It says that a given type implements a set of functions. But as with C++ templates, it's effectively resolved at compile time. (Well, the implementation is quite a bit different, but that's the rough idea.)
Now, ADTs and type classes are great. But if you find yourself using crazy hacks to recreate an OO class hierarchy in Haskell, you're probably fighting against the language. Either structure your program differently, or find a different language.
I agree - type overloading says templates to me rather than inheritance. C++'s tuple class lets you do some of the cool listy type things you can do in Haskell. Using typedef tuple<double, double> FloatPoint and taking it from there seems a lot more like the Haskell example and would be less code - one line each for the typedefs and a one-line function to implement <<. (Not taking anything away from Haskell, which I'm completely in love with.)
The typedef tuple strategy doesn't let you distinguish between types except by the types and ordering of their fields. If you later have a constructor for another ADT (or even the same one) which also takes two Float arguments, you end up with multiple typedefs for tuple<double, double>.
I would say the closest OO analog to ADTs is the Visitor pattern: You first fix the number of classes and then implement the different functions (visitors)
This is in contrast with the normal OO polymorphism/method where you first define set of methods and then implement the different classes.
----------
Type classes are more of a thing of their own. The template comparison is apt and I have heard Type Classes are supposedly very similar to the "Concepts" proposal that did not get in C++0x.