Scalable and Continuous
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 <email@example.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
> .. 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.