
On Mon, 2006-01-30 at 18:13 +0100, Sebastian Sylvan wrote:
Seems like a convenient feature to me.
Also, you may want to have a function which works on a list of any values which are both readable and showable. Say (mockup syntax):
foo ::
=> [a] foo = [ 1, True, myRocketLauncher ] Which would create a newtype called "ShowReadAble" or something with extistential types and also instantiate that type in both Show and Read.
I do agree that this is something I'd like in a lot of cases, and it probably would be used quite a bit more if it were convenient (and standardised!).
I leave it to someone else to figure out how to make this play nice with e.g. type inference.
I have often thought that it would be useful to have an existential corresponding to a class. There are several examples in Haskell where one wants to manipulate lists of values that support a common interface but are not necessarily the same type. Haskell makes it very convenient to do type based static dispatch but rather inconvenient to do runtime value dispatch. In general the preference for type based static dispatch is good. In OOP languages people often use the OOP value based dispatch when the Haskell style would be more appropriate, but it is not convenient in those languages. On the other hand there are sometimes when it really is better to do the value base dispatch. For example an extensible IO Handle data type. It is necessary to have lists of Handles so we can't have a Handle type class. One could have a record of functions. When I thought about this before I came to the conclusion that it would be convenient to be able to have a type class and a corresponding data type with the same name. The class gives the interface and the data type can be made a member of the type: class IStream s where readBlock :: s -> IO Block data IStream = IStream { istream_readBlock :: IO Block } instance IStream IStream where readBlock s = istream_readBlock s abstractIStream :: IStream s => s -> IStream abstractIStream s = IStream { istream_readBlock = readBlock s } So this allows us to have a type class so we can do ordinary type class stuff or if we need to manipulate streams of different underlying types only via their IStream interface then we can use abstractIStream to convert any instance of the IStream class to its most general instance, namely the IStream data type. But the above translation is a bit cumbersome and could be optimised. What's really going on is we're just converting from a class dictionary to an explicit dictionary. If this sort of thing were supported directly in the language then the dictionary conversion would be a no-op. So to summarise the feature, it might be nice to make doing runtime value-based dispatch through an interface (almost as) easy as the existing class mechanism which allows static type-based dispatch through an interface. Also to allow explicit conversion from one form to the other (anything in the class to a most general instance). Duncan