[Haskell-cafe] What does the `forall` mean ?

Lennart Augustsson lennart at augustsson.net
Sat Nov 14 20:14:34 EST 2009


Of the two declarations
>        data Fizzle a = Fizzle (b -> (a, b)) a
>        data Fizzle a = forall b. Fizzle (b -> (a, b)) a
only the second one is allowed (with some suitable extension).

Personally I think the first one should be allowed as well, with the
same meaning as the second one.
Some people thought it was to error prone not to have any indication
when an existential type is introduced,
so instead we are now stuck with a somewhat confusing keyword.

  -- Lennart

On Sat, Nov 14, 2009 at 4:55 PM, Mark Lentczner <markl at glyphic.com> wrote:
> On Nov 12, 2009, at 2:59 PM, Sean Leather wrote:
>>   foo :: forall x y. (x -> x) -> y
>>   bar :: forall y. (forall x . x -> x) -> y
>>
>> While neither function is seemingly useful, the second says that the higher-order argument must be polymorphic. I see two options:
>
> AHA! This is the bit of insight I needed! My confusion over forall was I thought that I understood that all Haskell types were as if there was a forall for all free type variables in front of the expression. For example, I think the following are the same:
>
>        fizz :: a -> String -> [a]
>        fizz :: forall a. a -> String -> [a]
>
> So why would you need forall? The example Sean explained is that if you want to control the scope of the existential quantification. And you can only "push the scope inward", since the outer most scope basically "forall"s all the free type variables (after type inference, I suppose.)
>
> I also think I understand that the implicit 'forall' inherent in Haskell falls at different places in various constructs, which also had me confused. For example, while the above two function type declarations are equivalent, these two data declarations aren't:
>
>        data Fizzle a = Fizzle (b -> (a, b)) a
>        data Fizzle a = forall b. Fizzle (b -> (a, b)) a
>
> This would be because the implicit 'forall' is essentially to the left of the 'data Fizzle a' section. I'm guessing that the same holds true for type and newtype constructs.
>
> Have I got this all correct?
>
> Would I be correct in thinking: The difference between these two is that the type b can be "fixed" upon application of amy to the first two arguments (given context), whereas bob applied to two arguments MUST return a function that is applicable to every type.
>
>        amy :: Int -> a -> b -> [Either a b]
>        bob :: Int -> a -> (forall b. b) -> [Either a b]
>
> Thanks for helping me understand...
>        - Mark
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list