
Niklas Broberg wrote:
On 4/27/06, Robin Bate Boerop
wrote: But, this code:
class CC a type C x = CC a => a x f, g :: C a -> Int f _ = 3 g x = f $ x -- the only change
The problem is exactly the use of $. $ is an operator, not a built-in language construct, and it has type (a -> b) -> a -> b. No forall's in there, so you cannot give it a function argument that is existentially quantified. Lots of people have been bitten by this when using the magic runST with type "forall a. (forall s. ST s a) -> a". Use parentheses when you have existentially quantified values and everything should be just fine. :-)
Just to point out that in this case the problem is even more subtle, because C x is an existential type and therefore is not supported at all in Haskell at present. You cannot even apply 'f' to anything. It is made more confusing by the fact that the type checker appears to accept g x = f x. However this is a red herring, because you can't actually apply 'f' to anything in practice eg f (A1 3) where A1 is an instance of CC, would give an error also. In contrast, (forall s. ST s a) is not a true existential, since we are here just simulating an existential by making use of the ST constructor to store the info about what 's' was used so that it can be recovered by pattern matching. The previous example I posted *does* work with $. Regards, Brian.