Also accepted by 7.0.4 and 7.2.1, but rejected by 6.12.1. However, it complains about -XFlexibleContexts, not -XConstrainedClassMethods:
[1 of 1] Compiling Main ( Test.hs, interpreted )Test.hs:3:0: All of the type variables in the constraint `Eq a' are already in scope (at least one must be universally quantified here) (Use -XFlexibleContexts to lift this restriction) When checking the class method: comp :: (Eq a) => a -> a -> Bool In the class declaration for `Compare'Failed, modules loaded: none.
You are absolutely right. See the H98 report http://www.haskell.org/onlinereport/decls.html. In 4.3.1. it says "the cxi may not constrain u", where u is the class variable, and cx is the context of a class method signature.
But (a) it's a bit fiddly to fix, (b) it's not clear what exactly it means for multi-parameter type classes, and more seriously it might break some existing programs which are inadvertently straying from H98 definition.
Sorry for reopening, but I think the situation can be improved, currently -XConstrainedClassMethods seems to do nothing and the documentation is misleading. I would support deprecating and eventually removing this pragma, and adding a notice to "Known bugs and infelicities" section.
More bugs. GHC only rejects the following program when -XConstrainedClassMethods is turned on. It should however always reject it, because op doesn't mention any type variables of Foo.
Patches are ready for review in D686, D687 and D688.
Instead of deprecating ConstrainedClassMethods, I have tried fixing it instead. D688 turns on ConstrainedClassMethods for all modes (Haskell98, Haskell2010 and default), to not break any programs. I added a section to "Known bugs and infelicities".
Existing tests tcfail149 and tcfail150 have been reenabled, and I added T7854 for the MultiParamTypeClasses case.
Thomie, thanks for working on this. Inspired by your patches I can see a simpler way to achieve the same goal, so I'll do that.
Specifically I plan to do this:
Fix the original bug simply by always doing a checkValidType on the entire selector-id type. That includes an ambiguity check which is precisely what we need.
Implement the check when ConstrainedClassMethods is off as a special check that does nothing else.
As ticket:7854#comment:71080 acknowledges, GHC has not been making the claimed check for ages. Rather than making ConstrainedClassMethods on by default (as you propose), I plan to make it implied by MultiParamTypeClasses, which means that we are out of Haskell-98 land anyway. This means that some programs may break, but (a) the error message suggests adding ConstrainedClassMethods (b) the fix is easy. If necessary (e.g. on a Stackage run) we can make it on-by-default in 7.10 to ease transition.
It has been around for a long time, but I know at least a few of us were rather startled when we started getting error messages about it and every occurrence I've found so far is a module where I have FlexibleContexts already enabled.
It's not so hard, and it is truthful, to add ConstrainedClassMethods to those libraries. But if the CLC advises, we can also make FlexibleContexts imply it.
Remember this is not in 7.10 so libraries have time to adapt.
That was me speaking as me, not in any official capacity. =) I had honestly thought FlexibleContexts was the extension for this sort of thing until now.
Putting on my CLC hat for a bit, the main reason I can see why it'd be nice to have FlexibleContexts "just work" is it means we don't have to make the hackage trustees go back and retrofit all sorts of old versions of packages with base upper bounds wherever they find themselves encountering this issue.
But mostly that rises to the left of "nice to have" not really "have to have".
I'm relaxed about what we choose here. It really matters little; and it's been a long-standing bug in GHC.
You do have a point: that FlexibleContexts sounds as if it has to do with type-signature contexts (and it does); and so does ConstrainedClassMethods. So perhaps it would be more intuitive to make FlexibleContexts imply ConstrainedClassMethods than MultiParamTypeClasses?
But I bet there are packages that use MultiParamTypeClasses but not FlexibleContexts. So
Perhaps we should try making FlexibleContexts imply ConstrainedClassMethods, but notMultiParamTypeClasses, just to see what happens.
If it's painful, then maybe the path of least resistance is to make both imply ConstrainedClassMethods.
Any views from others? Would someone like to try the experiment?