# [Haskell-cafe] what is a difference between existential quantification and polymorhic field?

Bruno Oliveira bruno.oliveira at comlab.ox.ac.uk
Thu Sep 21 07:47:03 EDT 2006

```Hello Bullat,

>considered as different:

>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

-------------- next part --------------
An HTML attachment was scrubbed...