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

Reply via email to