In article <[EMAIL PROTECTED]>, Ben Rudiak-Gould <[EMAIL PROTECTED]> wrote:
> And it would be nice to be able to pass around values of type > (exists t. Interface t => t), which behave just like OOP interface > pointers. A value of "type" (exists t. Interface t => t) consists of two values, one of type t, and one "dictionary" value. For that reason a data type is used to represent this (and a newtype type cannot be). So what's the difference? Data provides another layer of "thunkage". For instance: data D = MkD Int; newtype N = MkN Int; Then (MkN undefined) is the same as undefined, but (MkD undefined) is not. So how does this apply to (exists t. Interface t => t)? Well, you'd have two different versions of "undefined" depending on whether calculation of the dictionary was part of the undefinition. > I don't see how > > openInputStream :: FilePath -> IO (exists t. InputStream t => t) Bear in mind you can't even write IO (forall t. whatever) in Haskell. > would cause any more problems than > > data Foo = forall t. InputStream t => Foo t > openInputStream :: FilePath -> IO Foo > > What am I missing? Simply that undefined is not the same as (Foo undefined). Quite separately, if InputStream happens to look like this: class InputStream t where { f1 :: t -> something; f2 :: t -> something'; f3 :: t -> something''; -- etc. }; where none of the somethings refer to t, you'd be better off with a data-type: data InputStream { f1 :: something; f2 :: something'; f3 :: something''; -- etc. }; This is a much better way of doing semi-OOP. AFAIK you can't really do proper OOP-style extensibility in Haskell at all (and "exists" wouldn't help either). -- Ashley Yakeley, Seattle WA _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell