为什么使用数据类型我不能为这些数据属性提供相同的内部属性名称?
在这里,我不能在几个数据中重用变量名val
不编译
data Product = Product {val::String}deriving (Show, Eq)
data Price = Price {val::Double}deriving (Show, Eq)
data Discount = Discount { val::Double }deriving (Show, Eq)编译
data Product = Product {productVal::String}deriving (Show, Eq)
data Price = Price {priceVal::Double}deriving (Show, Eq)
data Discount = Discount { discountVal::Double }deriving (Show, Eq)发布于 2018-11-25 10:50:55
为什么使用数据类型我不能为这些数据属性提供相同的内部属性名称?
如果您定义了记录类型,那么您已经隐式地构造了一个"getter“。如果您定义的记录数据类型如下:
data Product = Product { val :: String } deriving (Show, Eq)然后Haskell将构造一个函数:
val :: Product -> String它获取给定Product对象的Product。
如果稍后定义一个新的记录数据类型:
data Price = Price { val :: Double } deriving (Show, Eq)然后定义两个版本的val,从而导致名称冲突。
DuplicateRecordFields扩展
(GHC)自8.0.1以来拥有一个扩展DuplicateRecordFields,允许指定两种具有相同字段名的记录数据类型。
使用相同的记录名进行模式匹配,或者在构造记录时使用相同的记录名称没有问题,例如:
productToPrice :: Product -> Price
productToPrice (Product {val = x}) = Price { val = 3 }不会产生任何问题,因为val在Product { val = x }中显然是指在Product数据构造函数中定义的val,而在Price { val = 3 }中的val是指Price数据构造函数的val。
但是,如果我们使用val作为函数,它将造成歧义:
Prelude> val (Product "foo")
<interactive>:15:1: error:
Ambiguous occurrence ‘val’
It could refer to either the field ‘val’,
defined at <interactive>:1:25
or the field ‘val’, defined at <interactive>:2:21我们可以添加函数的签名来指定要使用哪个val:
Prelude> (val :: Product -> String) (Product "foo")
"foo"或者通过指定Product "foo"的类型,我们获得了同样的效果:
Prelude> val (Product "foo" :: Product)
"foo"但是,如果val具有相同的类型,或者具有一些泛型意义,那么最好引入类型类型,从而在那里定义val函数。
https://stackoverflow.com/questions/53466606
复制相似问题