
Ryan Ingram wrote:
A common mistake (and a confusing bit about typeclasses) is that whether or not the constraints on an instance apply are irrelevant.
Specifically, the code "instance (Applicative f, Eq a) => AppEq f a" means that, given any types f and a, I can tell you how to make them an instance of AppEq. But I also ask you to please add the constraints "Applicative f" and "Eq a". That is to say, only the stuff on the right of the => apply when determining whether an instance applies.
Or perhaps a simpler way of explaining it is that (metasyntactically) for the class: > class CLASS a1 ... an where > f1 :: t1 > ... > fn :: tn the instance declaration: > instance CONTEXT a1 ... an => CLASS a1 ... an where > f1 :: t1 > ... > fn :: tn means *exactly*: > instance CLASS a1 ... an where > f1 :: CONTEXT a1 ... an => t1 > ... > fn :: CONTEXT a1 ... an => tn The ability to add contexts to a typeclass instance is not syntactic sugar per se ---because the latter declaration would be an invalid instance of the class (allowing the syntax might permit instances where contexts are inconsistent across f1...fn)--- but it's still just a sugary way of simplifying the declaration. While the latter declaration is unbearably syntactically salted, it's straightforward for explaining this common mistake. There've been a number of proposals for different syntax to make the current arrangement less confusing to newcomers, none of which has gained widespread currency. In the fine Haskell tradition of leaving things odd until a proper solution is found, I think the correct approach is to redesign the meaning of the original declaration such that it *does* propagate the constraints at instance-selection time, rather than trying to find a nicer coat of paint for the old bikeshed. The OverlappingInstances and IncoherentInstances flags are varnish to make the current arrangement tenable, but they cover up a whole area that is ripe for research. The new type families work covers a nearby domain, but I think active context propagation deals with a different set of concerns. -- Live well, ~wren