问题是关于具有2种数据类型Transaction
和FormatModel
,它们都具有formatId
字段。为了防止添加类型签名以从formatId
或transaction
获取formatModel
,我创建了类型类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
有人可以解释为什么执行eta简化的实例可以正常工作,而另一个实例却不能正常工作吗?
最佳答案
消除重复记录字段的歧义必然是一种尽力而为的事情,因为它需要在类型检查之前发生(通常,在知道表达式中的名称指的是什么标识符之前,通常不能对表达式进行类型检查;这就是歧义消除的意思)正在做)。
您的无效示例与documentation中的无效示例等效:
data S = MkS { x :: Int }
data T = MkT { x :: Bool }
bad :: S -> Int
bad s = x s