On Sun, May 27, 2012 at 7:07 PM, Richard O'Keefe <ok@cs.otago.ac.nz> wrote:

On 26/05/2012, at 4:16 AM, David Turner wrote:
>
> I don't. I think the trouble is that classes don't add value in exercises of this size.

This was the key point, I think.
In this example, there wasn't any significant behaviour that could be moved
to superclasses.  For that matter, whether a supplier is plain, preferred,
or problematic is, one hopes, not a *permanent* property of a supplier.

Sometimes higher-order functions can substitute for classes.

Functors can always substitute for OO classes.  A class system is a functor from the set of objects to a set of methods, mediated by inheritance, or things like message-passing, duck typing, prototyping, etc.

Functions with the type Foo -> Foo can be easily used to implement a prototype based dispatch mechanism.  Indeed, this is a common Haskell pattern.  Define:

-- Library code:
defaultFoo :: Foo
defaultFoo = Foo { bar =  ..., baz = ... }

-- Client code
myFoo = defaultFoo { bar = myBar }

Things can get as complicated as you would like, up to and including inheritance, by using functors other than ((->) a)

The defining characteristic of OO is that objects are stateful, but self-contained entities.  How methods are defined and dispatched vary wildly across OO languages.