
David House wrote:
On 08/05/07, Matthew Sackman
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. Jules