什么时候UndecidableInstances安全?关于GHC扩展的一些一般性问题 [英] When is UndecidableInstances safe? Some general questions regarding the GHC extension

查看:157
本文介绍了什么时候UndecidableInstances安全?关于GHC扩展的一些一般性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 -XUndecidableInstances ,但我想我会要求详细说明。



假设我有两个多参数类型类型(允许使用-XMultiParamTypeClasses

  class Foo ab 
class Goo ab

现在,假设我有一个参数化的数据类型

  data bar ab 

当我的一个参数是的一个实例的一部分时,我想创建一个 Foo 的实例>咕。我不确定前面的句子是否使用了确切的术语,所以这里是我想要写的:

  instance(Goo cd)= > Foo d(酒吧广告)

我不允许没有 UndecidableInstances 扩展名。我是否认为这是因为该实例没有引用 c 类型?



应该I. ..


  1. 只需启用扩展程序?有人可以详细说明它能带来什么样的麻烦吗?

  2. 将另一个参数添加到 Foo 中,以便最后一个实例声明变得像 Foo cd(Bar ad)?这样做的一个问题是我可能有 Foo 的其他实例永远不会引用任何这样的第四类型参数(即有实例Foo AB 在我的代码的无关部分),所以这些会破坏。我宁愿修理我的实例,而不是我的课程。

  3. 用足够的参数创建一个新的类 FooGoo ?我觉得在这种情况下我会重复自己,但至少我不会破坏无关的类。

有没有人有任何智慧的话?

解决方案


我正确地认为这是因为实例没有参考c类型?


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


对于上下文中的每个断言:没有
类型的变量在
中的断言比在头部中出现的次数多

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

如果你不知道你想要完成什么,很难给出合理的设计建议,但首先要检查的是你是否真的需要拥有c作为Goo的参数。你可能能够表达你想要完成的事情:

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


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...

  1. Just enable the extension? Can somebody elaborate on what kinds of trouble it can get me into?
  2. Add another parameter to 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.
  3. 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?

解决方案

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

这篇关于什么时候UndecidableInstances安全?关于GHC扩展的一些一般性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆