John

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.

Simon



_______________________________________________
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime

Reply via email to