
On Tue, 2008-10-14 at 13:11 +0100, John Lato wrote:
I was just thinking about what I wish someone had told me when I started working with Haskell (not that long ago). It would have saved me a great deal of trouble.
A recent quote of mine from HWN: * ddarius: Here's the short guide to Haskell for OO programmers: Haskell isn't at all an OO language.
The Difference Between Interfaces and Type Classes.
Many "Introduction to Haskell for the OOper" style tutorials claim that type classes are like Interfaces (for languages with that feature). I now think that, although this is technically true, it's fundamentally misleading.
It's not technically true. Type classes and interfaces a la Java are very fundamentally different neither is remotely capable of doing what the other does. As my quote above suggests, essentially nothing transfers from OO programming to Haskell. Haskell has absolutely no support whatsoever for object-oriented programming. At best, you can try to encode objects.
In C# (and presumably Java), this sort of function is common: public IList GetListOfData()
In Haskell, a similar function may be GetListOfData :: (Foldable a, Indexable a) => IO a
In C#, it doesn't matter what the actual type returned by GetListOfData is, as long is it supports the IList interface. It's not uncommon for GetListOfData to make a choice between several different implementations, depending on the nature of the data to be returned. The following code is perfectly reasonable in C# :
// List and MyList are different classes if (something) { return new List(); } else { return new MyList(); }
The equivalent won't compile in Haskell, because the actual return type does matter, and *is determined by the calling code*. Our fictional GetListOfData can't return a List or a Mylist depending on some conditional, in fact it can't explicitly return either one at all, because the actual type of the result, as determined by the caller, could be either one, or something else entirely (ignoring the IO bit for the time being).
So I've come to the conclusion that stating type classes are like interfaces is misleading to newcomers to Haskell, because it leads people to think they should use type classes for the same sorts of problems OO-languages solve with interfaces. In turn this means new programmers are encouraged to use OO-style architecture in programs, reassured that they're in a "functional" idiom because they're using the "functionally-approved" feature of type classes. I think that if I had understood this earlier, I would have embraced functional idioms more quickly.
Incidentally, I'm still horrible at designing functional APIs and modules, but at least now I know it, and I'm no longer trying to force OO interfaces into Haskell. So I've made progress.
I strongly agree with the thrust of your email. This "type classes are kinda like interfaces" meme is horrible. The sooner newcomers realize type classes have nothing to do with object oriented programming, or likely anything they've seen before, the better. Unfortunately, there is a glut of crappy tutorials out there. Good introductions tend to deal with this much better and the best advice I can give is to simply ignore most or all tutorials and read or steer others to more comprehensive and better regarded/reviewed resources. For example, this is a line from RWH: "Typeclasses may look like the objects of object-oriented programming, but they are truly quite different." Also later there is another sidebar along those lines.