愚蠢的重复记录字段错误

时间:2017-06-23 06:42:47

标签: haskell

请考虑以下事项:

{-# LANGUAGE DuplicateRecordFields #-}

data A = A { name :: String }

data B = B { name :: String }

main = print $ name (A "Alice")

编译时,我收到以下消息(在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

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

main = print $ name ((A "Alice") :: A)

编译成功完成。

这是为什么?类型签名:: 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")

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

{-# 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")

似乎GHC只需要为每个唯一记录名称机械地添加一个类,并为每个数据类型中的每个记录添加一个实例。但这意味着name x == name y并不意味着xy的类型相同,但无论如何我都希望使用此扩展程序。

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

1 个答案:

答案 0 :(得分:6)

-XDuplicateRecordFields目前无法从参数中推断出类型。

请参阅GHC user guide section about this extension

  

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

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

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