[Haskell-cafe] Instances that shouldn't overlap

wren ng thornton wren at freegeek.org
Sun Nov 30 16:53:57 EST 2008

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,

More information about the Haskell-Cafe mailing list