Re [Haskell-cafe] Vanishing polymorphism

Jules Bean jules at
Thu May 10 02:26:20 EDT 2007

David House wrote:
> On 08/05/07, Matthew Sackman <matthew at> wrote:
>> > :t let f r s = let g (fn::forall n . (Num n) => n -> n) = return 
>> (fn r, fn s) in (return negate) >>= g in f
> Ah, I may have been off the mark earlier. I think the problem is due
> to the fact that you can't pass higher-order polymorphic functions
> around. I.e., the following is a classic example of something people
> expect to work, but doesn't:
>  runST $ ...
> runST is a rank-2 polymorphic function, and you're attempting to pass
> it as a parameter to the ($) function, which doesn't work. I think
> your problem is similar. Here's the module I used to investigate
> goings on:

It's a bit more subtle than that, I think.

You can pass rank-2 functions around, but type inference will not unify 
ordinarily polymorphic variables with rank-2 types. So ($) has the type 
(a -> b) -> a -> b ; but the implicit restriction here (and in all such 
haskell types) is that the 'a' and 'b' are rank-1. At least if you want 
automatic inference. I suspect that with explicit type annotations you 
can declare the precise rank-2 version of ($) that you want, and then it 
will work.

Summary: If you want to pass a rank-2 function around, the function 
receiving it as a parameter has to have an explicitly annotated type.


More information about the Haskell-Cafe mailing list