carlohamalainen/playground — pull request #1 by mbrcknl (2013-12-11 07:20:48+00:00)
Title: Add "forall" type quantifier to activate ScopedTypeVariables.

A type variable is "scoped" when both:

- the `ScopedTypeVariables` extension is enabled, for example in a `LANGUAGE` pragma, and
- the type variable is *explicitly* `forall`-quantified at the desired scope.

Otherwise, the type variable is implicitly scoped to the the type signature in which it appears. In that case, it behaves just as if it had a name distinct from all other type variables in your program.

Thus, without any `forall` quantifiers, each signature gets its own distinct `b` type variable. Internally, GHC gives the `b` in the `mapParser` its original name, and the `b` in the `body` signature the name `b1`.

The thing that is likely confusing you is that when you give "f" an explicit signature `f :: a -> b`, you get a *third* distinct type variable, say `b2`.

Since this means `f :: forall a b. a -> b`, you'd need to pass a type coercion operator to call `mapParser`! No such function exists in the safe fragment of Haskell. But of course, if you assume someone can pass you such a function, you can trivially use it to satisfy the type checker. Hence, there is no error when this signature is given.

Now here's the trick: when you *remove* the signature from `f`, it's given an inferred type. The result type inferred from it's use in `body` is the `b` in the signature for `body`, which was internally renamed to `b1`. The result type inferred from its position in the list of arguments to mapParser is the `b` in the signature for `mapParser`. Both of these are fixed ("rigid") by their respective signatures, so neither can be instantiated to the other. BOOM!

But clearly, you intended the `b` in the signature for `body` to refer to the `b` in the signature for `mapParser`, and the way to tell GHC this is to add the `forall` quantifier to the signature for `mapParser`.

Hope that helps!