With some spare boredom I had this morning, I was skimming the section on functors in RWH. A little ways down they introduce the type:
data Eq a => Bar a = Bar a instance Functor Bar where fmap f (Bar a) = Bar (f a)
And point out how the constraint does not allow a valid functor instance. But what if it did?
What I’m getting at is that nobody ever uses constraints on data definitions like that, because they’re basically useless (AFAIK, they just impose the constraint on each constructor and nothing more). Perhaps they could work in this way: the mention of the type Bar a implies the constraint Eq a. Thus:
fmap :: (a -> b) -> Bar a -> Bar b
The caller already provides the dictionaries Eq a and Eq b for you, because the types “Bar a” and “Bar b” come from his environment. I’m not sure what I mean by environment there.
The time you would be required to provide a dictionary would be if you used a Bar in the body of a function without mentioning it in the type signature.
If this makes sense (I’m not convinced it does in the least), it might be a nice way to solve the class restriction problem.