愚蠢的复制记录字段错误 [英] Silly duplicated record fields error

查看:104
本文介绍了愚蠢的复制记录字段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  { - #LANGUAGE DuplicateRecordFields# - } 

data A = A {name :: String}

data B = B {name :: String}

main = print $ name(AAlice)

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

  duplicatedrecords.hs:7:16:error:
模糊发生'名称'
它可以引用字段'name',
定义在duplicatedrecords.hs:5:14
或字段'name',在duplicatedrecords.hs:3:14处定义

但是,如果我修改主要行如下:

 < code $ main $ print $ name((AAlice):: A)

编译成功。



这是为什么?类型签名 :: A 似乎对我来说是多余的,因为 A 构造函数确实使编译器清楚(AAlice)类型为 A 。但由于某种原因,它有所作为。为什么是这样的,有没有一种方法可以在不乱抛垃圾的情况下进行编译?



注意:



值得注意的是,下面的代码编译得很好:

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

class Name t where
name:t - >字符串

实例名称A其中name = a_name
实例名称B其中name = b_name
$ b $ main = print $ name(AAlice)

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

  { - #LANGUAGE TypeFamilies# - } 

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

class名称t其中
类型系列T t
名称:: t - > T t

实例名称A其中
类型TA =字符串
名称= a_name

实例名称B其中
类型TB = Int
name = b_name

main =打印$ name(AAlice)

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



只是想知道是否有什么棘手的问题

$ c>目前不会从参数中推断出类型。



请参阅关于此扩展程序的GHC用户指南部分


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

但情况正在改善。因此,我们可能会期望并最终获得期望的行为:

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


Consider the following:

{-# LANGUAGE DuplicateRecordFields #-}

data A = A { name :: String }

data B = B { name :: String }

main = print $ name (A "Alice")

When compiled, I get the following message (on 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

But if I modify the main line as follows:

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

Compilation proceeds successfully.

Why is this? The type signature :: A seems redundant to me, as surely the A constructor makes it clear to the compiler that (A "Alice") is of type A. But for some reason it makes a difference. Why is this and is there a way I can get this to compile without littering extra type signatures everywhere?

Note:

It's worth noting that the following compiles fine:

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

We can even go further as follows, allowing different result types:

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

It seems like GHC just has to mechanically add a class for each unique record name and an instance for each record in each data type. This will mean however that name x == name y not implying that the types of x and y are the same but I'd expect that when using this extension anyway.

Just wondering if there's anything tricky I'm missing here regarding the implementation or that it just needs someone to do it?

解决方案

-XDuplicateRecordFields currently doesn't infer types from arguments.

See GHC user guide section about this extension.

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. Thus the following is ambiguous:

But things are improving. So we might expect and finally get desired behavior:

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

这篇关于愚蠢的复制记录字段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆