
... was mildly surprised by the need for -XUndecidableInstances when deriving the 'Show' instance for the heterogenous N-ary product 'NP':
Hi Viktor, yes 'Undecidable' sounds scary, but it isn't. There's been much debate: should we find a less scary name? Presumably your program compiles and runs OK with that switched on(?) Providing your program compiles, it is type-safe. The risk with -XUndecidableInstances is that you might throw the compiler into a loop, in which case you'll get a stack depth check, with an unhelpful error message. See the Users Guide on UndecidableInstances, also this is a faq on StackOverflow.
deriving instance All (Compose Show f) xs => Show (NP f xs)
Yes the constraint on that instance violates the Paterson Conditions (see Users Guide), the constraint is no smaller than the instance head. The P Conditions aim to make each step of instance resolution smaller, by strictly decreasing "constructors and variables (taken together ...". But that constraint has a count of 4, same as the head.
I guess I should also ask whether there's a way to define something equivalent to 'Compose' without 'UndecidableSuperClasses', and perhaps the two are not unrelated. Not exactly related, but again superclass instance resolution wants to make the problem smaller at each step. The definition for class Compose has a constraint no smaller than the class head (3 variables).
[ Perhaps I should be more blasé about enabling these extensions, but I prefer to leave sanity checks enabled when possible. ]
Yes that's a sensible policy. The trouble with -XUndecidableInstances is that it's a module-wide setting, so lifts the check for all instances of all classes. There are/were several proposals to make this a per-instance or per-class pragma. But they got no support in the proposals process. AntC