UndecidableInstances 什么时候安全?有关 GHC 扩展的一些常见问题
我知道 -XUndecidableInstances 的文档 ,但我想我应该要求详细说明。
假设我有两个多参数类型类(允许 -XMultiParamTypeClasses< /a>)
class Foo a b
class Goo a b
现在,假设我有一个参数化数据类型
data Bar a b
,当它的参数之一是 Goo
实例的一部分时,我想创建一个 Foo
实例。我不确定前一句使用了确切的术语,所以这就是我想写的内容:
instance (Goo c d) => Foo d (Bar a d)
如果没有 UndecidableInstances
扩展,我就不允许这样做。我是否正确地认为这是因为实例没有引用 c
类型?
我应该...
- 只启用扩展吗?有人可以详细说明它会给我带来什么样的麻烦吗?
- 向
Foo
添加另一个参数,以便最后一个实例声明变成类似于Foo cd (Bar ad)
?这样做的一个问题是,我可能有其他Foo
实例,它们从未对任何此类“第四类型参数”进行任何引用(即存在instance Foo A B
形式的实例> 在我的代码的不相关部分),所以这些会破坏。我宁愿修复我的实例,而不是我的类。 - 创建一个具有足够参数的新类
FooGoo
?在这种情况下,我会觉得我在重复自己,但至少我不会破坏不相关的课程。
有没有人有什么至理名言?
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...
- Just enable the extension? Can somebody elaborate on what kinds of trouble it can get me into?
- Add another parameter to
Foo
, so that the last instance declaration becomes something likeFoo c d (Bar a d)
? A problem with this is that I might have other instances ofFoo
that never make any reference to any such "fourth type parameter" (i.e. there are instances of the forminstance Foo A B
in unrelated parts of my code), so these would break. I'd rather fix my instance, not my class. - Create a new 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,您的代码不符合(来自此处< /a>):
您应该是安全的。当涉及到
OverlappingInstances
时,事情只会变得非常棘手(并且依赖于编译器),而当你使用IncoherentInstances
时,事情就会变得非常糟糕。如果不了解更多关于您想要完成的任务,就很难提供合理的设计建议,但首先要检查的是您是否真的需要将 c 作为 Goo 的参数。你也许可以这样表达你想要完成的事情:
Yes, your code does not adhere to (from here):
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 goIncoherentInstances
.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: