<HTML>
<FONT FACE="MS Shell Dlg" DEFAULT="FACE"><FONT SIZE="1" POINTSIZE="8" DEFAULT="SIZE">Hello Bullat,<BR>
<BR>
>now i'm reading Haskell' proposals and found that these two things<BR>
>considered as different:<BR>
><BR>
><FONT COLOR=0000ff><U>http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantification<FONT COLOR=000000 DEFAULT="COLOR"></U><BR>
><FONT COLOR=0000ff><U>http://hackage.haskell.org/trac/haskell-prime/wiki/PolymorphicComponents<FONT COLOR=000000 DEFAULT="COLOR"></U><BR>
><BR>
>can you please explain me what is the difference between<BR>
><BR>
>data Ex = forall a. Num a => Ex a<BR>
><BR>
>and<BR>
><BR>
>data Po = Po (forall a. Num a => a)<BR>
><BR>
<BR>
With existencial types you know what what the type of the thing <BR>
you are packing is:<BR>
<BR>
> t = Ex (3 :: Int)<BR>
<BR>
and you forget about it once it is packed.<BR>
<BR>
However, with polymophic components the following is a type error<BR>
<BR>
> t = Po ( 3 :: Int)<BR>
<BR>
because you are required to provide a polymorphic value (forall a . Num a => a)<BR>
and you have given it a value Int. However, the following is valid:<BR>
<BR>
> t1 = Po 3<BR>
<BR>
since (3 :: forall a . Num a => a).<BR>
<BR>
So, perhaps an easy way to think about existencials is that they are almost like:<BR>
<BR>
> data Ex a = Ex a<BR>
<BR>
except that the type "a" is lost as soon as you construct such a value. <BR>
<BR>
Where does this make a difference? <BR>
<BR>
Try the following two definitions: <BR>
<BR>
> addPo :: Po -> Po -> Po<BR>
> addPo (Po x) (Po y) = Po (x + y)<BR>
<BR>
> addEx :: Ex -> Ex -> Ex<BR>
> addEx (Ex x) (Ex y) = Ex (x + y)<BR>
<BR>
The first one works, the second one doesn't. The reason that the first works is because "x" and "y" <BR>
are polymorphic and thus they can be unified. This is more/less equivallent to:<BR>
<BR>
> addPo' :: (forall a . Num a => a) -> (forall a . Num a => a) -> (forall a . Num a => a)<BR>
> addPo' x y = x + y<BR>
<BR>
The second does *not* work because when you created the values for the existencials you assumed <BR>
some concrete types. So, "x" could be an Integer and "y" could be a Float and therefore, you should <BR>
not be allowed to perform this operation.<BR>
<BR>
> also, ghc66 adds impredicative polymorphism. how it differs from<BR>
> unqualified existentials?<BR>
<BR>
I have not tried ghc66, but I think one of the things you should be able to do and that <BR>
is perhaps helpful for understanding existencial is:<BR>
<BR>
> myList :: [forall a . Num a => a]<BR>
> myList = [3 :: Int, 4 :: Float, 6 :: Integer]<BR>
<BR>
which in previous versions of GHC would need to be written as:<BR>
<BR>
> myList :: [Ex]<BR>
> myList = [Ex (3 ::Int), Ex (4 :: Float), Ex (6 :: Integer)]<BR>
<BR>
Hope this helps.<BR>
<BR>
Cheers,<BR>
<BR>
Bruno Oliveira<BR>
</HTML>