我有一个带有函数依赖的多参数类型类:
class Multi a b | a -> b
我还有一个简单的、非单射类型的同义词族:
type family Fam a
我想写一个Multi
的示例,在第二个参数中使用Fam
,如下所示:
instance Multi (Maybe a) (Fam a)
但是,此示例不被接受。GHC报告以下错误消息:
error:
• Illegal type synonym family application in instance: Fam a
• In the instance declaration for ‘Multi (Maybe a) (Fam a)’
幸运的是,这里有一个解决方法。我可以执行一个常用的技巧,将一个类型从示例头中移到等式约束中:
instance (b ~ Fam a) => Multi (Maybe a) b
这个示例被接受了!然而,我开始思考,我开始怀疑为什么这个转换不能应用于Multi
的 * 所有 * 示例。毕竟,函数依赖不是意味着每个a
只能有一个b
吗?在这种情况下,GHC似乎没有理由拒绝我的第一个示例。
我找到了GHC Trac ticket #3485,它描述了一个类似的情况,但是该类型类没有涉及函数依赖,所以该ticket(正确地)被关闭为无效。然而,在我的情况下,我认为函数依赖避免了ticket中描述的问题。是否有什么我忽略了的,或者这真的是GHC中的一个疏忽/缺失的特性?
1条答案
按热度按时间6jjcrrmo1#
目前,如果类型类中存在函数依赖,GHC不支持示例声明的第二个参数中的类型同义词家族。这是因为当类型同义词家族出现在示例头中时,它们没有完全展开,所以GHC不能保证第二个参数只有一个可能的类型。
作为一种解决方法,您可以使用一个等式约束,就像您在示例中所做的那样,它允许您将类型同义词族移到示例头之外并移到约束中。这将允许GHC接受该示例。