UndecidableInstances何时安全?关于GHC扩展的一些一般性问题

时间:2011-02-16 13:43:52

标签: haskell ghc

我知道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类型?

我应该......

  1. 只需启用扩展程序?有人可以详细说明它可以带给我什么样的麻烦?
  2. 将另一个参数添加到Foo,以便最后一个实例声明变为Foo c d (Bar a d)?这样做的一个问题是我可能有Foo的其他实例永远不会引用任何这样的“第四类参数”(即在我的代码的不相关部分中存在instance Foo A B形式的实例) ,所以这些会破裂。我宁愿修理我的实例,而不是我的班级。
  3. 创建一个包含足够参数的新类FooGoo?在这种情况下,我觉得我在重复自己,但至少我不会打破不相关的课程。
  4. 有没有人有任何智慧的话语?

1 个答案:

答案 0 :(得分:10)

  

我认为这是因为实例没有引用c类型吗?

是的,您的代码不符合(来自here):

  

对于上下文中的每个断言:否   类型变量有更多的出现   断言比在头脑中

一般情况下,除非您添加一起形成循环的其他实例,否则您应该是安全的。当涉及到OverlappingInstances时,事情变得非常毛茸茸(并且依赖于编译器),当你去IncoherentInstances时,它就会变得非常邪恶。

如果不了解你想要完成的事情,很难给出合理的设计建议,但首先要检查的是你是否真的需要将c作为Goo的参数。你或许可以像这样表达你想要完成的事情:

class Goo d where
    bar :: d c -> Int
    baz :: Quux c => d c -> Int