我有一个具有函数依赖性的多参数类型类:
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
的
all实例。毕竟,函数依赖不是意味着每个
b
只能有一个 a
吗?在这种情况下,GHC 似乎没有理由拒绝我的第一个实例。
我发现 GHC Trac 票证#3485,它描述了类似的情况,但该类型类不涉及功能依赖性,因此该票证(正确地)被视为无效而关闭。然而,在我的情况下,我认为功能依赖性避免了票证中描述的问题。有什么我忽略的地方,或者这确实是 GHC 中的一个疏忽/缺失的功能吗?
根据评论,我认为为什么第一个实例 Multi (Maybe a) (Fam a) 不起作用,如果第二个实例是由于内存分配,为什么当您实现此解决方案时它起作用
instance (b ~ Fam a) => Multi (Maybe a) b
因为在这个中你要移动(b ~ Fam a)到Multi(也许a),其中b仍然作为储备
但这就是我的想法