为什么 DuplicateRecordFields 不能有类型推断?

Why DuplicateRecordFields cannot have type inference?

相关post:

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

However, we do not infer the type of the argument to determine the datatype, or have any way of deferring the choice to the constraint solver.

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

有人知道这样做的充分理由吗?是因为当前类型系统的限制吗?

您会对 OverloadedRecordFields 感兴趣,它仍在实施中。


当前的实现是有意削弱的,以免一次引入太多新内容。推断记录投影类型结果是打开了一个讨厌的蠕虫罐头(前面提到的扩展地址)。

考虑以下 GHCi 交互

ghci> data Record1 = Record1 { field :: Int }
ghci> data Record2 = Record2 { field :: Bool }
ghci> :t field

现在 field 的类型应该是什么?不知何故,我们需要一种方法来捕捉 "any record with a field called field" 的概念。为此,OverloadedRecordFields引入了一个新的内置类型class

The new module GHC.Records defines the following:

class HasField (x :: k) r a | x r -> a where
  getField :: r -> a

A HasField x r a constraint represents the fact that x is a field of type a belonging to a record type r. The getField method gives the record selector function.

那么,从我们上面的例子来看,就好像下面的实例是由 GHC 神奇地生成的(事实上,这并不是真正会发生的事情,但这是一个很好的初步近似)。

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

instance HasField "field" Record2 Bool where
  getField (Record2 f) = f

如果你有兴趣,我建议阅读提案。我没有提到的另一个功能是 IsLabel class。一旦所有这些都实现了(还有一些用于更新记录),我期待能够 (这样我就可以停止声明以下划线开头的字段名称并为 [=25= 启用 TemplateHaskell ]).