Sat, 30 Dec 2000 14:50:04 +1100, Fergus Henderson <fjh@cs.mu.oz.au> pisze:
It's just something that didn't make it into Haskell 98. Hugs and ghc offer a language extension for that. It will almost certainly be in the next revision of Haskell. See <http://www.haskell.org/ghc/docs/latest/set/existential-quantification.html>.
Existential quantification is not always necessary to obtain an equivalent of dynamic binding. Dynamic binding is often used instead of function closures or IO action closures, especially in languages which lack real closures. An object of the abstract type "output IO stream" is equivalent to a record (tuple, whatever) of values of types like Char -> IO () -- write a character String -> IO () -- write a string IO () -- flush IO () -- close "Dynamic binding" is a fancy way of saying that the function to be called will be chosen at runtime. So we have exactly this, expressed in a simpler way. OO languages provide subtyping and inheritance. This is harder. Subtyping done by explicit coercions up can be done, but it's tedious to write (my new record scheme proposal tries to help here), and it's impossible to coerce down. Inheritance can be done by delegation. It does not work to express everything like OO languages usually do, because they are not typesafe. That's why (IMHO) that OO languages are usually dynamically typed. OO-like subtyping is usually not able to accurately express binary methods or the requirement that an argument must provide several interfaces at once. Haskell's classes should be left for constraints on types (as opposed to values). I want to sort a list, I compare elements with each other. It does not make sense to say that an element is comparable. Comparable with what? A _type_ can be comparable (i.e. ordered), or the ordering itself may be expressed as an object, but it does not belong to objects being compared. It follows that it does not make sense to have "a heterogeneous collection of comparable objects" or casting an object up to the type "comparable". But I might not care if the fact that something is a stream open for writing is a property of its type which is not statically known (as when stream is modelled as a class) or a property of all objects of the given type which is concrete (as when stream is modelled as a record of functions) - because I usually work with one such object at a time. When it's expressed as a class, I gain the possibility of extracting from the same object at different places properties belonging to different interfaces, without explicit coercions. But it is necessary to use existential quantification for heterogeneous collections. When it's expressed as a record of functions, all streams are flattened to a single interface, it is more convenient to use but the information about the exact kind of stream is not available. These approaches can be mixed. With my new record scheme proposal it is more convenient to introduce a class of types of objects from which the interface of a stream open for writing (expressed as a record of functions) can be extracted. This class needs not to be explicitly defined (only the record of functions). Stream operations can also be seen as provided by the object itself instead of always going through the extracted interface. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK