【发布时间】:2019-03-26 13:12:57
【问题描述】:
如果我使用类型类来重载方法,那是在“字典传递样式”中实现的。也就是说,该方法获得了一个额外的参数(没有出现在表面 Haskell 中);为了解决重载,该方法按其“正确”参数的类型查找字典;并从字典中提取方法实现。 As described in this q, for example.
但是没有方法的类型类呢?它们可以用作约束。有他们的字典吗?它包含什么?
举个具体的例子:
module M where
class C a -- no methods
-- no instances in module M
f :: C a => a -> Bool
f x = blah
此模块中没有C 的实例,所以如果M 被导入到其他模块(带有C 实例),f 的字典查找将如何编码?
通常的情况是类C 有方法;在f 等式的 RHS 上有电话给他们;所以想要的C a 被编码为方法调用的字典查找。
补充问题:(如果有人还在听)
2a。对于具有超类约束的无方法类型类:约束在字典中的什么位置? comment on a ticket from SPJ 似乎表明它是字典数据构造函数的参数。
2b。对于有约束的无方法类型类实例:同样,约束在字典中的什么位置?
动机
cmets 中的@Daniel 正在询问这些 q 的动机。除了更好地理解编译器内部......
GHC 将表面 Haskell 转换为内部表示:System FC,它在每个函数应用程序中都有明确的类型签名。 (这些应用程序必须包括应用类的字典。)我试图了解类和实例声明的所有类型相关组件在字典中的位置;弄清楚 FC 中的术语如何获得与原始 Haskell 等效的表示。然后我不明白 [没有方法的类型类] 是如何适应的。因为这些类不能直接作为表面 Haskell 中的术语出现,而只能作为约束出现。那么它必须是在术语级别表示它的此类的字典。
如果你想问这是怎么回事:FC 中似乎有一个限制,它不能表示函数依赖。与无法生成类型级证据有关。然后我想了解这种限制是如何产生的/FunDeps 不能(或目前没有)代表什么?
【问题讨论】:
-
这里似乎有两个不同的问题。您不能调用
f,因为没有C的实例。但是如果你添加一个实例,比如instance C Char,那么f 'a'可以正常工作。 -
好的。我应该学会不要匆忙编辑 q。再次编辑。参考@Chepner 的评论,我不能打电话给
f,但我可以导出它。我故意不想在这个模块中释放可释放的约束,所以我强制f的调用者访问字典。 -
感谢@DanielWagner 的回答。如果您还在听,我添加了一个补充 q。
-
“超类约束”和“约束”之间有什么区别(这两件事是我在您的问题 2a 和 2b 之间看到的唯一文本差异)?至于“他们去哪里”,我不确定这个问题是否明智。由于字典在表面语言中不明确可用,因此无法观察其中特定位的 哪里。
-
2b “带有约束的实例”表示对实例的约束。不,我们无法查看字典,但您在这里和链接中的 SPJ 都提供了示例。我认为这是 GHC 用来证明术语类型满足约束条件的机制,即使它没有调用方法。