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.
1 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,
Class1andClass2in the list:Class1is a (indirect) superclass ofClass2, orClass2is a (indirect) superclass ofClass1, orClass1andClass2have a common subclassClass3in 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
mis given in such an instance declaration, a default is used. Multiple classes can give a default form. If bothClass1andClass2have a default implementation, andClass1is a (indirect) superclass ofClass2, then the default fromClass1is ignored. It is an error if more than one default remains after this process.
2 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 Ctx => Alias a = (Class1 a, Class2 a, ..) where ...
The body can contain default implementations of methods from
Class1,Class2and their superclasses. -
In a context,
Alias ais treated the same as(Head, Class1 a, Class2 a, ..). -
In an instance head,
Alias ais treated the same as(_Alias a, Class1 a, Class2 a, ..),
where_Aliasis considered a subclass ofClass1andClass2that contains the default methods from the class alias body.class (Head, Class1 a, Class2 a, ..) => _Alias a where ...
The name
_Aliasis a fresh name. I.e. it can not be refered to, it is used only for the purpose of this specification.
