Simon Peyton-Jones wrote:
Interesting example!
| Coincidentally, I tripped over this subtlety myself just last night. (I, | too, often use '$' to avoid nested parentheses.) I concluded it was an | instance of the "partial-application restriction" that I found described in | section 7.11.4 of the GHC 5.02 User's Guide (still accessible at the GHC web | site if you look carefully enough).
No, that's not the reason. That restriction has been lifted.
Consider this simpler program;
foo = id runST
Now we have id :: forall a. a -> a
So to apply 'id' to 'runST' we'd have to instantiate the type variable 'a' to runST's type 'forall b. (forall s. ST s b) -> b'
But GHC only implements predicative polymorphism; it does not allow you to instantiate a type variable with a for-all type. It would be nice to lift this restriction, but I don't know how do to so without losing type inference.
Now, the error message you get is deeply obscure, I grant you. Trouble is, this variant IS ok:
foo = id wibble
wibble :: ((forall s. ST s b) -> b) -> b
Why? For the same reason that this is OK
foo = id reverse
That, is we can instantiate the type of the argument to a monotype (a type without for-alls).
Sorry, I don't understand yet. Why isn't the "forall s" in wibble's type a problem?
So it's not easy to see how to spot the bad case and give a better message. If this comes up again I'll think about it again. Meanwhile, I'm going to put it under "higher-rank polymorphism gives strange error message" file.
Simon
-- Dean