forall (What does it do)

I've seen forall used in a few places related to Haskell. I know their is a type extension call "explicit forall" but by the way it is documnted in some places, the documentation makes it sound like it does nothing usefull. However on Page 27 of Haskell's overlooked object system:
We define an existential envelope for shape data. data OpaqueShape = forall x. Shape x => HideShape x “Opaque shapes are (still) shapes.” Hence, a Shape instance: nstance Shape OpaqueShape where readShape f (HideShape x) = readShape f x writeShape f (HideShape x) = HideShape $ writeShape f x draw (HideShape x) = draw x When building the scribble list, we place shapes in the envelope. let scribble = [ HideShape (rectangle 10 20 5 6) , HideShape (circle 15 25 8) "
It seems that forall can be used as a form of up casting. That is if we have a parametric type we can treat the parametric types as homogeneous: The paper did not seem to regard this feature too highly:
By contrast, the explicit constraint for the existential envelope cannot be eliminated. Admittedly, the loss of type inference is a nuance in this specific example. In general, however, this weakness of existentials is quite annoying. It is intellectually dissatisfying since type inference is one of the added values of an (extended) Hindley/ Milner type system, when compared to mainstream OO languages. Worse than that, the kind of constraints in the example are not necessary in mainstream OO languages (without type inference), because these constraints deal with subtyping, which is normally implicit. We do not use existentials in OOHaskell http://homepages.cwi.nl/~ralf/OOHaskell/paper.pdf
but can't we just use the read shape function above if we want to be able to infer based on types. I understand that haskers tend to like things well typed but surely their are times when we would like to be able to flatten the type of our data somewhat. On another note, I also wonder how forall relates to type families. I know their are certain restrictions on where we can use type families in haskell. I wonder if we can get around these somewhat using forall.

On May 5, 2010, at 9:52 PM, John Creighton wrote:
I've seen forall used in a few places related to Haskell. I know their is a type extension call "explicit forall" but by the way it is documnted in some places, the documentation makes it sound like it does nothing usefull.
However on Page 27 of Haskell's overlooked object system:
We define an existential envelope for shape data. data OpaqueShape = forall x. Shape x => HideShape x
... (presumably:) class Shape x where area :: x -> Float ... etc...
It seems that forall can be used as a form of up casting.
Yes, but you can do this without the type class magic, and have the same degree of safety.
data Shape = Square Int | Rectangle Int Int | Circle Float Float | etc... data OpaqueShape = HideShape Shape area :: OpaqueShape -> Float area = ...
These constructs are structurally equivalent. The extra layer of abstraction doesn't really add anything in either case. HideShape (as a function) is an isomorphism onto Shapes in both cases.

On May 6, 2:13 am, Alexander Solla
Yes, but you can do this without the type class magic, and have the same degree of safety.
data Shape = Square Int | Rectangle Int Int | Circle Float Float | etc... data OpaqueShape = HideShape Shape area :: OpaqueShape -> Float area = ...
These constructs are structurally equivalent. The extra layer of abstraction doesn't really add anything in either case. HideShape (as a function) is an isomorphism onto Shapes in both cases.
You're example isn't as easy to extend. If we want to add shapes we have to edit the original code. We cannot add other shapes at different places in the code. I prefer the type class magic. It is more general and generic.
participants (2)
-
Alexander Solla
-
John Creighton