At first glance, there obvious distinctions between the two kinds of “class”. However, I believe there are more similarities:
- Both have different kinds of constructors.
- Both define a group of operations that could be applied to a particular type of data, in other words, they both define an Interface.
I can see that “class” is much more concise in Haskell and it’s also more efficient. But, I have a feeling that, theoretically, “class” and “abstract class” are identical.
What’s your opinion?
Er, not really, no.
For one thing, Haskell’s type classes don’t have constructors; data types do.
Also, a type class instance isn’t really attached to the type it’s defined for, it’s more of a separate entity. You can import instances and data definitions separately, and usually it doesn’t really make sense to think about “what class(es) does this piece of data belong to”. Nor do functions in a type class have any special access to the data type an instance is defined for.
What a type class actually defines is a collection of identifiers that can be shared to do conceptually equivalent things (in some sense) to different data types, on an explicit per-type basis. This is why it’s called ad-hoc polymorphism, in contrast to the standard parametric polymorphism that you get from regular type variables.
It’s much, much closer to “overloaded functions” in some languages, where different functions are given the same name, and dispatch is done based on argument types (for some reason, other languages don’t typically allow overloading based on return type, though this poses no problem for type classes).