Original-Via: uk.ac.nsf; Mon, 7 Oct 91 21:36:58 BST

| Date:         Tue, 1 Oct 1991 17:46:05 +0100
| From: Mikael Rittri <[EMAIL PROTECTED]>
| Subject:      Why can't Real be made a subclass of Enum?
|
| I tried to insert the  Enum  class (page 30) into the diagram
| of numeric classes (figure 7, page 55), but got confused.
|
| Every standard type in class  Real  is individually declared
| to be an instance of  Enum, using the same functions
| (numericEnumFrom  and  numericEnumFromThen, page 90).
|
| Yet,  Real  is technically not a subclass of  Enum.
| The declaration of  Real  (page 57 or 86) is
|
|     class (Num a, Ord a) => Real a where
|         toRational  ::  a -> Rational
|
| so I wonder why it isn't
|
|     class (Num a, Ord a, Enum a) => Real a where
|         toRational  ::  a -> Rational
|         enumFrom     =  numericEnumFrom
|         enumFromThen =  numericEnumFromThen

It would be nice to be able to do this.  Another case like this
is that Integral could be a subclass of Ix.  But alas,

| I guess the answer is that class operations must either be defined
| at the topmost class (in this case  Enum), or for each individual
| type, but not at an "intermediate" class (like  Real).

We could still make Real a subclass of Enum, but that would merely
require Enum instances for each instance of Real, rather than
generating them automatically.

| In "The Next Stage" section, page vii, it says that in the
| future, a class declaration may include default methods for
| operations of its superclasses, which _override_ the superclass's
| default methods.
|    But in the Enum/Real case,  Enum  has no default methods for
| enumFrom  and  enumFromThen, so no overriding is necessary.

That is, we could include the default methods

         enumFrom     =  numericEnumFrom
         enumFromThen =  numericEnumFromThen

in the Enum class declaration, but I think this is bad form:
These methods use operations of class Real (and its superclasses)
What happens if some random, nonnumeric type is given an Enum
instance declaration without any method definitions?

| It would be interesting to see an explanation of the technical problems
| of having default definitions in an "intermediate" class declaration.

Yes, perhaps now is the time to discuss this.  As far as I know,
the only difficulty with providing the generalization mentioned
in the "The Next Stage" section is the multiple inheritance problem:

                A
              /   \
             B     C
              \   /
                D


With this class inclusion structure, what default methods are available
to instances of class D if the declarations of classes B and C both
provide default methods for some operations of class A that the class
D declaration does not provide default methods for?  One solution
is that D not inherit any default method where there is a conflict.
We could further require that D provide a default method in such a
case.  Should there be a way for D to resolve a conflict by
specifying which method to inherit?  If we have qualified names,
this could be done by allowing Class.method as a name.

I think we were wise not to open this can of worms in Haskell 1.0 or 1.1,
but I think it is worth doing.  Let me close with one more application
of this idea:

I would like to define a subclass of Ord:

        data Comparison = LT | EQ | GT

        class (Ord a) => TotalOrd a  where
                compare:: a -> a -> Comparison

                compare x y | x == y     =  EQ
                            | x <  y     =  LT
                            | otherwise  =  GT

And here I can also override the slightly odd default methods for
min and max from class Ord, which assume a type with a preorder or
partial order, but not a total order:

                min x y | x <= y     =  x
                        | otherwise  =  y
                max x y | x >= y     =  x
                        | otherwise  =  y

(Actually, I would want to rename Ord PartialOrd and call the above
class Ord, and also provide a superclass of PartialOrd called Preord,
which would not be a subclass of Eq and would contain the operators
<= and >= but not < and >, but that's a slightly different subject.)

--Joe

Reply via email to