I know of the documentation for -XUndecidableInstances, but I thought I'd ask for an elaboration.
Suppose I have two multi-parameter typeclasses (allowed with -XMultiParamTypeClasses)
class Foo a b
class Goo a b
Now, suppose I have a parameterized data type
data Bar a b
which I want to make an instance of Foo when one of its parameters is part of an instance of Goo. I'm not sure the previous sentence uses exact terminology, so here's what I want to write:
instance (Goo c d) => Foo d (Bar a d)
I'm not allowed to without the UndecidableInstances extension. Am I correct in thinking this is because the instance doesn't refer to the c type?
Should I...
Foo, so that the last instance declaration becomes something like Foo c d (Bar a d)? A problem with this is that I might have other instances of Foo that never make any reference to any such "fourth type parameter" (i.e. there are instances of the form instance Foo A B in unrelated parts of my code), so these would break. I'd rather fix my instance, not my class.FooGoo with enough parameters? I would feel like I'm repeating myself in that case, but at least I wouldn't break unrelated classes.Does anyone have any words of wisdom?
Am I correct in thinking this is because the instance doesn't refer to the c type?
Yes, your code does not adhere to (from here):
For each assertion in the context: No type variable has more occurrences in the assertion than in the head
In general, you should be safe unless you add other instances that would, together, form a loop. Things only get really hairy (and compiler-dependent) when it comes to OverlappingInstances, and rightout evil when you go IncoherentInstances.
Without knowing more about what you're trying to accomplish it's hard to give sound design advice, but the first thing to check is whether you really, really need to have c as a parameter to Goo. You might be able to do express what you want to accomplish like this:
class Goo d where
bar :: d c -> Int
baz :: Quux c => d c -> Int
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With