我知道the documentation for -XUndecidableInstances,但我想我会要求详细说明。
假设我有两个多参数类型类(允许-XMultiParamTypeClasses)
class Foo a b
class Goo a b
现在,假设我有一个参数化数据类型
data Bar a b
当我的一个参数是Foo
实例的一部分时,我想创建Goo
的实例。我不确定前面的句子是否使用了完整的术语,所以这就是我想写的内容:
instance (Goo c d) => Foo d (Bar a d)
如果没有UndecidableInstances
扩展名,我就不允许这样做。我是否认为这是因为实例没有引用c
类型?
我应该......
Foo
,以便最后一个实例声明变为Foo c d (Bar a d)
?这样做的一个问题是我可能有Foo
的其他实例永远不会引用任何这样的“第四类参数”(即在我的代码的不相关部分中存在instance Foo A B
形式的实例) ,所以这些会破裂。我宁愿修理我的实例,而不是我的班级。FooGoo
?在这种情况下,我觉得我在重复自己,但至少我不会打破不相关的课程。有没有人有任何智慧的话语?
答案 0 :(得分:10)
我认为这是因为实例没有引用c类型吗?
是的,您的代码不符合(来自here):
对于上下文中的每个断言:否 类型变量有更多的出现 断言比在头脑中
一般情况下,除非您添加一起形成循环的其他实例,否则您应该是安全的。当涉及到OverlappingInstances
时,事情变得非常毛茸茸(并且依赖于编译器),当你去IncoherentInstances
时,它就会变得非常邪恶。
如果不了解你想要完成的事情,很难给出合理的设计建议,但首先要检查的是你是否真的需要将c作为Goo的参数。你或许可以像这样表达你想要完成的事情:
class Goo d where
bar :: d c -> Int
baz :: Quux c => d c -> Int