具有不同字段名的记录的haskell变体

具有不同字段名的记录的haskell变体,haskell,record,variant,Haskell,Record,Variant,鉴于此: data Foo = Bar { name :: String } | Baz { nickname :: String } 函数name和nickname的类型似乎都是Foo->String: :t name name :: Foo -> String :t nickname nickname :: Foo -> String 但是,这些定义不完整,因为以下两个表达式都会引发模式匹配错误: name $ Baz { nickname = "Bob" } nickna

鉴于此:

data Foo = Bar { name :: String } | Baz { nickname :: String }
函数
name
nickname
的类型似乎都是
Foo->String

:t name
name :: Foo -> String

:t nickname
nickname :: Foo -> String
但是,这些定义不完整,因为以下两个表达式都会引发模式匹配错误:

name $ Baz { nickname = "Bob" }
nickname $ Bar { name = "Fred" }
是否可以完成
名称
昵称
的定义,例如:

name Baz { nickname = n } = ...

nickname Bar { name = n } = ...

在hugs中尝试此操作会产生错误,如“变量名的多个声明”。

不,这是不可能的。字段名是作用域的顶级函数,因此不能重新定义或扩展。使它们成为完整的函数就像使
head
成为一个函数一样是不可能的。

试试-extension,它允许您将数据构造函数提升为一种类型


请注意,您需要GHC7.4.1,它是在12天前发布的。现在是问这个问题的好时机

你可以从一开始就给他们取相同的名字。在您的案例中,有什么可以阻止这种情况发生吗?这在这一点上更像是一个理论问题,但是假设
名称
昵称
属于不同的类型,那么您就不能给它们相同的字段名。另请参见:如何使用它来帮助记录字段名?我没有看到它。好吧,它不会帮助你说
name$Baz{昵称=“Bob”}
,但它允许你使用
name
作为
::Bar->String
,这至少让问题变得明确。正如Daniel Fischer所说,询问
Baz的
名称
就像询问
[]
头部
,因此您最好是将其明确化。感谢您的回复-我将查看DataTypes扩展。