[Haskell-cafe] what is a difference between
existential quantification and polymorhic field?
bruno.oliveira at comlab.ox.ac.uk
Thu Sep 21 07:47:03 EDT 2006
>now i'm reading Haskell' proposals and found that these two things
>considered as different:
>can you please explain me what is the difference between
>data Ex = forall a. Num a => Ex a
>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.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe