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