Pivoting off some recent questions, I figured I'd turn the spotlight on the old bogeyman, OverlappingInstances
.
A few years ago I might've been asking this question in earnest: after all, you can provide useful default instances and others can override them with more specific ones when they need to, what can be so bad about that?
Along the way I've absorbed some apprecation for the viewpoint that OverlappingInstances
is really not so clean, and best avoided; mainly stemming from the fact that it's not very well-grounded theoretically, unlike other big extensions.
But thinking about it, I'm not sure if I could explain what's really so bad about it to another person, if I were asked.
What I'm looking for is specific examples of ways in which using OverlappingInstances
can lead to bad things happening, whether it's by subverting the type system or other invariants, or just general unexpectedness or messiness.
One particular problem I know of is that it breaks the property that merely adding or removing a single module import can't change the meaning of your program, because with the extension on, a new instance overlap could be silently added or removed. While I can see why that's unpleasant, I don't see why it's earth-shatteringly awful.
Bonus question: As long as we're on the subject of useful but not theoretically well-grounded extensions that can lead to bad happenings, how come GeneralizedNewtypeDeriving
doesn't get the same bad rap? Is it because the negative possibilities are more easy to localize; that it's easier to see what would cause problems and say, "don't do that"?
(Note: I would prefer if the brunt of the answer focuses on OverlappingInstances
, not IncoherentInstances
which needs less explanation.)
EDIT: There are also good answers to a similar question here.