愚蠢的重复记录字段错误

Cli*_*ton 9 haskell

考虑以下:

{-# LANGUAGE DuplicateRecordFields #-}

data A = A { name :: String }

data B = B { name :: String }

main = print $ name (A "Alice")
Run Code Online (Sandbox Code Playgroud)

编译时,我得到以下消息(在GHC 8.0.2上)

duplicatedrecords.hs:7:16: error:
    Ambiguous occurrence ‘name’
    It could refer to either the field ‘name’,
                             defined at duplicatedrecords.hs:5:14
                          or the field ‘name’, defined at duplicatedrecords.hs:3:14
Run Code Online (Sandbox Code Playgroud)

但如果我main按如下方式修改该行:

main = print $ name ((A "Alice") :: A)
Run Code Online (Sandbox Code Playgroud)

编译成功完成.

为什么是这样?类型签名:: A对我来说似乎是多余的,因为A构造函数肯定会使(A "Alice")类型的编译器清楚A.但由于某种原因,它会产生影响.为什么这样,有没有一种方法可以让我编译而不会乱丢额外的类型签名?

注意:

值得注意的是,以下编译正常:

data A = A { a_name :: String }
data B = B { b_name :: String }

class Name t where
  name :: t -> String

instance Name A where name = a_name
instance Name B where name = b_name

main = print $ name (A "Alice")
Run Code Online (Sandbox Code Playgroud)

我们甚至可以进一步如下,允许不同的结果类型:

{-# LANGUAGE TypeFamilies #-}

data A = A { a_name :: String }
data B = B { b_name :: Int }

class Name t where
  type family T t
  name :: t -> T t

instance Name A where
  type T A = String
  name = a_name

instance Name B where
  type T B = Int
  name = b_name

main = print $ name (A "Alice")
Run Code Online (Sandbox Code Playgroud)

似乎GHC只需要为每个唯一记录名称机械地添加一个类,并为每个数据类型中的每个记录添加一个实例.然而,name x == name y这意味着并不意味着类型xy相同,但我仍然期望在使用此扩展时.

只是想知道这里是否有任何棘手的问题,或者只是需要有人这样做?

She*_*rsh 6

-XDuplicateRecordFields 目前不会从参数推断出类型.

有关此扩展,请参阅GHC用户指南部分.

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

但事情正在改善.所以我们可能期望并最终得到理想的行为:

https://prime.haskell.org/wiki/TypeDirectedNameResolution