
On Sat, 2008-06-21 at 00:20 +0400, Bulat Ziganshin wrote:
probably, you don't understand differences between OOP classes and type classes. look at http://haskell.org/haskellwiki/OOP_vs_type_classes and papers mentioned there
I took the liberty to update some of the C++ code on that page so that the code will compile and work as expected. Reading the rest of the page I have a question regarding section 4.2, Type classes correspond to parameterized abstract classes (Gabriel Dos Reis). This is probably more related to C++ than Haskell, so not all readers might find it of interest. --- off topic --- Looking at 4.2, it's interesting to see how type classes are translated into C++. Admittedly C++ isn't the prettiest language to look at, but I feel one must be fair, and the code presented at the Wiki is too complex, using virtuals and templates where they're not needed. Normal overloading suffices. Operator definitions can already be placed outside of a class scope, e.g. the many overloads of << to print something to a stream. By default these definitions cannot access private members of their operands but the code at the Wiki has the same problem. Just a small example: // --- somewhere in a file --- struct Aap { int x; explicit Aap(int x) : x(x) {} Aap add(Aap const& other) const { return Aap(x + other.x); } }; // --- somewhere in another file --- Aap operator+(Aap const& lhs, Aap const& rhs) { return lhs.add(rhs); } Overloading functions is not different. I've omitted some other (more complex) ways you can achieve the same (aside from normal overloads it's also allowed to introduce new specializations later). At the time of writing it's not possible in C++ to restrict a type to allow a certain operation (concepts[1] will hopefully fill that gap some day, but I think it'll be a long time before tool support is ready for prime-time). Rather, it's common to just use the operation and let the compiler generate a (sometimes very cryptic) error message if it cannot find the right code. [1]: http://www.generic-programming.org/software/ConceptGCC/ A very poor man's solution to see if an operation is defined would be: template<typename T> struct has_add; template<> struct has_add<Aap> {}; int main() { (void)sizeof(has_add<Aap>); // okay (void)sizeof(has_add<int>); // fails to compile, put useful comment here } It's not hard to add some primitive predicate logic (at compile time) to resemble type classes in some sense, but I think this is off-topic enough as it is. Regards, Niels