Eta reduce和DuplicateRecordFields语言扩展

Rik*_*Rik 7 haskell

问题是有两种数据类型,Transaction并且FormatModel都有formatId字段.为了防止添加类型签名formatId来自transactionformatModel,我创建了类型类HasFormat:

class HasFormat a where
  formatId_ :: a -> FormatId

instance HasFormat Transaction where
   formatId_  x = formatId x -- gives error because ambiguous occurrence ‘formatId’

instance HasFormat FormatModel where
  formatId_  = formatId -- this works
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么eta减少实现的实例正在工作而另一个没有?

Rei*_*ton 6

消除重复记录字段的消息必然是一种尽力而为的事情,因为它需要类型检查之前发生(在你知道其中的名称所指的标识符之前,你通常不能键入检查表达式;这就是消除歧义的原因.这样做).

您的非工作示例等同于文档中的此非工作示例:

data S = MkS { x :: Int }
data T = MkT { x :: Bool }
bad :: S -> Int
bad s = x s
Run Code Online (Sandbox Code Playgroud)

  • @chi来自docs:"我们不推断确定数据类型的参数类型".第一个版本不起作用,因为它必须查看参数的类型.第二个版本有效,因为没有参数 - 根据`formatId_`的类型选择正确的`formatId`.好像有人写了`formatId :: X - > Y`而不是`formatId(x :: X)`. (4认同)