
On Tue, 2006-01-31 at 13:28 +0000, Duncan Coutts wrote:
On Tue, 2006-01-31 at 13:59 +0100, Wolfgang Jeltsch wrote:
Am Montag, 30. Januar 2006 19:02 schrieb Duncan Coutts:
[...]
I have often thought that it would be useful to have an existential corresponding to a class.
How would this work with multi-parameter classes, constructor classes, etc.? If you propose something that only works in conjunction with a special kind of classes I would hesitate to include such thing in a Haskell standard.
As John Mecham said it'd be for single parameter type class with a parameter of kind *.
But you're probably right that people should get more experience with using this technique before giving special support in the language to make it convenient.
As Bulat noted we can already use this construction:
class (Monad m) => Stream m h | h->m where vClose :: h -> m () vIsEOF :: h -> m Bool .....
data Handle = forall h . (Stream IO h) => Handle h
instance Stream IO Handle where vClose (Handle h) = vClose h vIsEOF (Handle h) = vIsEOF h .....
But we have to give the name of the most general instance a different name to the class which is rather inconvenient.
So perhaps we should start with allowing a class a data type to have the same name and in a future standard think about making it easy to define Bulat's Handle instance above with a short hand like:
class (Monad m) => Stream m h | h->m where vClose :: h -> m () vIsEOF :: h -> m Bool ..... deriving data Stream
Actually this is unnecessary. All we need is: class (Monad m) => Stream m h | h->m where vClose :: h -> m () vIsEOF :: h -> m Bool newtype Handle = exists s. Stream s => Handle s deriving Stream So all we need is existentials and newtype-deriving. Duncan