Haskell 不可判定的实例何时是安全的?关于GHC扩展的一些一般性问题
我知道,但我想我会要求详细说明 假设我有两个多参数TypeClass(允许使用) 现在,假设我有一个参数化的数据类型Haskell 不可判定的实例何时是安全的?关于GHC扩展的一些一般性问题,haskell,ghc,Haskell,Ghc,我知道,但我想我会要求详细说明 假设我有两个多参数TypeClass(允许使用) 现在,假设我有一个参数化的数据类型 data Bar a b 当它的一个参数是Goo实例的一部分时,我想创建一个Foo的实例。我不确定前一句话是否使用了确切的术语,因此我想写以下内容: instance (Goo c d) => Foo d (Bar a d) 如果没有不可判定实例扩展名,我是不允许这样做的。我认为这是因为实例没有引用c类型,对吗 我应该 只启用扩展?有人能详细说明一下这会给我带来什么样的
data Bar a b
当它的一个参数是Goo
实例的一部分时,我想创建一个Foo
的实例。我不确定前一句话是否使用了确切的术语,因此我想写以下内容:
instance (Goo c d) => Foo d (Bar a d)
如果没有不可判定实例
扩展名,我是不允许这样做的。我认为这是因为实例没有引用c
类型,对吗
我应该
Foo
,以便最后一个实例声明类似于foocd(Bar a d)
?这样做的一个问题是,Foo
的其他实例可能从未引用过任何此类“第四类型参数”(即,在我的代码的不相关部分中存在形式为instance Foo A B
的实例),因此这些实例将中断。我宁愿修复我的实例,而不是我的类FooGoo
?在这种情况下,我会觉得我在重复我自己,但至少我不会中断无关的课程重叠实例时,事情才会变得非常棘手(并且依赖于编译器),而当涉及到不连贯的情况时,事情就会变得很糟糕
如果你不知道你想要完成什么,就很难给出合理的设计建议,但是首先要检查的是你是否真的,真的需要用c作为Goo的参数。您可以这样做来表达您想要实现的目标:
class Goo d where
bar :: d c -> Int
baz :: Quux c => d c -> Int
谢谢这带来了一定程度的澄清。我认为good
约束也会使food(Bar a d)
实例不可用,除非Goo
具有函数依赖性d->c
——否则,编译器如何决定使用哪个Goo
实例?如果所有Goo
实例都将c
作为类型变量,而不是出现在d
中,那么@barsoap建议删除该类型参数就是一种方法。
class Goo d where
bar :: d c -> Int
baz :: Quux c => d c -> Int