[Haskell-cafe] C++ class = neutered (haskell class + haskell existential)

Gabriel Dos Reis gdr at integrable-solutions.net
Sun Aug 20 00:26:30 EDT 2006


John Meacham <john at repetae.net> writes:

| On Tue, Aug 15, 2006 at 08:36:28PM +0200, Gabriel Dos Reis wrote:
| > Roughly Haskell type classes correspond to parameterized abstract
| > classes in C++ (i.e. class templates with virtual functions 
| > representing the operations).  Instance declarations correspond to
| > derivation and implementations of those parameterized classes.
| 
| There is a major difference though, in C++ (or java, or sather, or c#,
| etc..) the dictionary is always attached to the value, the actual class
| data type you pass around.

I suspect that most of the confusion come from the fact that people
believe just because virtual functions are attached to objects, 
they cannot attach them to operations outside classes.  That, to my
surprise, hints at a deeper misappreciation of both type classes and
so-called "OO" technology.  Type classes are more OO than one might
realize. 

The dictionary can be attached to the operations (not just to the values) by
using objects local to functions (which sort of matierialize the
dictionary).  Consider

    // Abstract class for a collection of classes that implement
    // the "Num" mathematical structure
    template<typename T>
      struct Num {
          virtual T add(T, T) const = 0;
      };

    // Every type must specialize this class template to assert
    // membership to the "Num" structure.  
    template<typename T> struct Num_instance;

    // The operation "+" is defined for any type that belongs to "Num".
    // Notice, membership is asserted aby specializing Num_instance<>.
    template<typename T>
      T operator+(T lhs, T rhs)
      {
         const Num_instance<T> instance;  
         return instance.add(lhs, rhs);
      }

    // "Foo" is in "Num"
    struct Num_instance<Foo> : Num<Foo> {
       Foo add(Foo a, Foo b) const { ... }
    };


The key here is in the definition of operator+ which is just a formal
name for the real operation done by instance.add().

I appreciate that inferring and building the dictionary (represented
here by the "instance" local to operator+<T>) is done automatically by
the Haskell type system.
That is  one of the reasons why the type class notation is a nice sugar.
However, that should not distract from its deerper OO semantics.
    

[...]

| in haskell you can do
| 
| class Monoid a where
|         mempty :: a
| 
| in OOP, this cannot be done because where does the dicionary come from?

See above.  I believe a key in my suggestion was "paramaterized
abstract classes", not just "abstract classes".


More information about the Haskell-Cafe mailing list