Scalable and Continuous

Dylan Thurston dpt@math.harvard.edu
Sat, 17 Feb 2001 17:58:55 -0500


On Fri, Feb 16, 2001 at 10:21:57PM -0600, Matt Harden wrote:
> Marcin 'Qrczak' Kowalczyk wrote:
> > Wed, 14 Feb 2001 23:27:55 -0600, Matt Harden <matth@ninenet.com> pisze:
> > > such defaults would only be legal if the superclass did not define
> > > a default for the same function.
> > 
> > Not necessarily. For example (^) in Num (of the revised Prelude)
> > has a default definition, but Fractional gives the opportunity to
> > have better (^) defined in terms of other methods. When a type is an
> > instance of Fractional, it should always have the Fractional's (^)
> > in practice. When not, Num's (^) is always appropriate.
> What happens if classes A and B are superclasses of C, all three
> define a default for function foo, and we have a type that's an instance
> of A and B, but not C, which doesn't override foo?  Which default do we
> use?  It's not only a problem for the compiler to figure out, it also
> quickly becomes confusing to the programmer.  

(Presumably you mean that A and B are subclasses of C, which contains
foo.)  I would make this an error, easily found by the compiler.
But I need to think more to come up with well-defined and uniform
semantics.

> .. I'd rather just make the
> simple rule of a single default per function.  If multiple "standard"
> definitions for a function make sense, then be explicit about which one
> you want for each type; i.e.:
> 
>    instance Fractional MyFraction where
>       (^) = fractionalPow

This is another option.  It has the advantage of being explicit and
allowing you to choose easily in cases of ambiguity.  It is more
conservative, but possibly less convenient.

Best,
	Dylan Thurston