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
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe