[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,

>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.


Bruno Oliveira

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20060921/b7635ad6/attachment.htm

More information about the Haskell-Cafe mailing list