Haskell' - class aliases
simonpj at microsoft.com
Fri Apr 25 12:37:17 EDT 2008
OK here's a question about class alisas. You propose:
class Foo a where
foo :: a -> [a]
foo x = 
class Bar a where
bar :: a -> a
bar x = [x]
class alias FooBar a = (Foo a, Bar a) where
foobar :: a -> a
foobar x = x
foo x = bar x
I have a few minor questions about this that'd be worth clarifying on your main page
(a) I assume you can add a method 'foobar' not declared
in either Foo or Bar. Your very first example has this.
But it's contradicted later when you say that "One can declare an instance
of Num either by giving separate instances for Eq, Additive, Multiplicative"
(b) And I assume that you don't need to repeat the type
signatures for 'foo' and 'bar'.
(c) I think you intend that you can override the default methods
for foo and bar; and I have done so for method 'foo'.
Question: how does the above differ from this?
class (Foo a, Bar a) => FooBarSC a where
foobar :: a -> a
Here Foo, Bar are simply superclasses. From the point of view of a type signature there *no* difference:
f :: (FooBarSC a) => ...
gives access to all the methods of Foo and Bar. So what's the difference?
Answer (I believe): when you give an instance of FooBar
you give implementations for all methods of
Foo, Bar, and FooBar.
So the obvious question is: do we really need a new construct? Why not just use FooBarSC? Then we'd have to allow you to give implementations for superclass methods too:
instance FooBarSC Int where
foobar = ...
foo = ...
bar = ...
I think I believe (like you) that this is a bad idea. The main reason is that it's a totally unclear whether, given a FooBarSC Int instance declaration, should there be an instance for (Foo Int), always, never, or optionally?
However, I think you might want to articulate the reasons carefully, because we have two features that are really extremely close.
To put it another way, you could imagine re-expressing your proposal like this:
class (Eq a) && (Additive a, Multiplicative a) => Num a
meaning this: when you give an instance for (FooBar T) you
* MUST give implementations for the methods
of Addititive and Applicative
* MUST NOT give implementations for methods of Eq;
rather the Eq T instance must be in scope.
This is, I believe, what you mean by
class alias Num a = Eq a => (Additive a, Multiplicative a)
Now I'm not necessarily suggesting this as concrete syntax. But my point is that you're really asking for small modification of the existing superclass mechanism, that divides the superclasses into two groups, the "flat" ones (like Additive and Multiplicative) and the "nested" ones (like Eq). Is that right? If so, a syntax that is more suggestive of the current superclass declaration looks better to me.
This close relationship also suggests strongly that the answer to (a) above should be 'yes', since you can certainly add methods to a class with superclasses.
I won't say more until I'm sure I've understood your intent.
More information about the Haskell-prime