Superclass defaults
John Meacham's class alias proposal conflates two different issues:
- Class aliases: A single name for multiple classes.
- Method defaults in aliases: Allow defaults across classes.
I think it would be better to separate the two.
In particular, we would like Monad
to have a default implementation of Functor
's fmap
.
In John's propsal this is not possible, you need a new Monad_
class alias which contains the default.
Superclass defaults
- A class declaration can contain method defaults for methods in that class and in its (indirect) superclasses.
-
An instance declaration can specify multiple classes
instance (Class1 a, Class2 a, ...) where ...
Subject to the constraint that:
- No class appears more than once in the list.
- The arguments to each class are the same.
- For each pair of classes,
Class1
andClass2
in the list:Class1
is a (indirect) superclass ofClass2
, orClass2
is a (indirect) superclass ofClass1
, orClass1
andClass2
have a common subclassClass3
in the list.
In other words, the superclass relation gives a connected acyclic graph with a single source, the most specific class in the heirarchy.
-
If no implementation of a method
m
is given in such an instance declaration, a default is used. Multiple classes can give a default form
. If bothClass1
andClass2
have a default implementation, andClass1
is a (indirect) superclass ofClass2
, then the default fromClass1
is ignored. It is an error if more than one default remains after this process.
Class aliases
The above can be extended with class aliasses, this part of the propsal is exactly the same as John's.
-
A class alias is declared with the syntax
class alias Head => Alias a = (Class1 a, Class2 a, ..) where ...
The body can contain default implementations of methods from
Class1
,Class2
and their superclasses. -
In a context,
Alias a
is treated the same as(Head, Class1 a, Class2 a, ..)
. -
In an instance head,
Alias a
is treated the same as(_Alias a, Class1 a, Class2 a, ..)
,
where_Alias
is considered a subclass ofClass1
andClass2
that contains the default methods from the class alias body.class (Head, Class1 a, Class2 a, ..) => _Alias a where ...
The name
_Alias
is a fresh name. I.e. it can not be refered to, it is used only for the purpose of this specification.