Haskell' - class aliases

Simon Peyton-Jones simonpj at microsoft.com
Fri May 2 05:00:32 EDT 2008


This is good stuff, but I fear that in 3 months time it'll be buried in our email archives. In contrast, your original web page is alive and well, and we were able to start our discussion based on it

So can I suggest that you transfer your web page to the Haskell' wiki (simply a convenient, editable place to develop it), or to the haskell.org wiki (likewise).  And that, as the design gets fleshed out, you try to reflect the current state of play there? I don't want this work to be lost!

Ok, on to your email:

=============== Desugaring the class alias decl =================
| there are two different desugaring rules, one for instances, one for the
| alias appearing anywhere other than an instance declaration:
| > g :: A a => a -> b
| > g = ...
| translates to
| > g :: (S a, C1 a, C2 a) => a -> b
| > g = ...
| the triplet of (S a, C1 a, C2 a) is completely equivalent to (A a) in
| all ways and all places (other than instance heads)

Notice that this part *is* exactly true of a superclass with no methods

        class (S a, C1 a, C2 a) => A a where {}

That's not necessarily bad; but it does make it harder to figure out when to user a superclass and when to use a class alias.  Does that make sense?

In fact, I suggest the following (**): the class alias

> class alias S a => A a = (C1 a, C2 a) where
>         f1 = nd1

desugars to

  class (S a, C1 a, C2 a) => A a

The class alias decl *also* affects the desugaring of instances, still to come, but by desugaring the class alias into an ordinary class, you don't have to say *anything* about
        g :: (S a, C1 a, C2 a) => a -> b
vs      g :: (A a) => a -> b

=============== Desugaring instanc decls =================
| now for instance declarations
| > instance A a where
| >         f2 = bf2
| expands to
| > instance (S a) => C1 a where
| >         f1 = nd1
| > instance (S a) => C2 a where
| >         f2 = bf2
| >         f3 = d3

Do you really mean that? Presumably 'a' is not a type variable here?  Furthermore, instance decls typically have a context.  Unless I have profoundly misunderstood, I think you mean this:

  instance (Foo a, Bar b) => A (a,b) where
        f1 = bf1

expands to

  instance (Foo a, Bar b) => C1 (a,b) where
        f1 = nd1

  instance (Foo a, Bar b) => C2 (a,b) where
        f2 = bf2
        f2 = d3

Notice the *absence* of an instance for (S (a,b)).  It's up to the *user* to ensure that there is such an instance, perhaps, say

        instance Foo a => S (a,b) where ...

In this way S is behaving just like any ordinary superclass.  If we have

        class S a => T a
then given an instance
        instance (Foo a, Bar b) => T (a,b)
it's up to the user to ensure that there is an instance for S (a,b).

With the desugaring (**) I proposed above, we'd add one more instance:
        instance (Foo a, Bar b) => A (a,b)

| Hopefully the generalization to arbitrary numbers of classes is clear...

I'm not sure either way.  Let's get this written up first.


More information about the Haskell-prime mailing list