
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 I have to say though that I am surprised that us Haskell folk are not more interested in making it easy or even possible to have abstract values accessed via interfaces. Classes make it easy and elegant to have type based dispatch but for the few times when value based dispatch really is necessary it's a pain. The fact that we've suffered with a non-extensible abstract Handle type for so long is an example of this. Duncan