[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
> 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.
More information about the Haskell-Cafe