为什么DuplicateRecordFields不能进行类型推断?

Lar*_*rry 7 haskell types records ghc

相关文章:如何消除选择器功能的歧义?

https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields

但是,我们不会推断参数的类型来确定数据类型,或者有任何方法可以将选择推迟到约束求解器.

实际上很烦人,这个功能没有实现.我试图查找多个来源,但我找不到他们决定不推断类型的原因.

有谁知道这个的好理由?是因为当前类型系统的限制吗?

Ale*_*lec 9

您将对OverloadedRecordFields哪些仍在实施感兴趣.


目前的实施有意削弱,以免一次性引入太多新东西.推断记录投影类型最终会打开一堆令人讨厌的蠕虫(前面提到的扩展地址).

考虑以下GHCi交互

ghci> data Record1 = Record1 { field :: Int }
ghci> data Record2 = Record2 { field :: Bool }
ghci> :t field
Run Code Online (Sandbox Code Playgroud)

field现在的类型应该是什么?不知何故,我们需要一种方法来捕捉"任何带有字段的记录"的概念field.为此,OverloadedRecordFields介绍了一个新的内置类型类

新模块GHC.Records定义了以下内容:

class HasField (x :: k) r a | x r -> a where
  getField :: r -> a
Run Code Online (Sandbox Code Playgroud)

一个HasField x r a约束代表的事实,x是类型的字段a属于一个记录类型r.该getField方法给出了记录选择器功能.

然后,从我们上面的例子中,好像GHC神奇地生成了以下实例(实际上实际上并不会发生什么,但它是一个很好的初步近似).

instance HasField "field" Record1 Int where
  getField (Record1 f) = f

instance HasField "field" Record2 Bool where
  getField (Record2 f) = f
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣,我建议您阅读该提案.我没有提到的另一个功能是IsLabel课程.一旦所有这一切都是实现(和其他的一些更新记录),我期待着能够得到我的镜头自由(这样我就可以停止,宣布开始用下划线字段名称和实现TemplateHaskellmakeLenses).