2011-03-08 99 views
8

请考虑下面的记录定义:F#记录:字段名称相同

type A = { F1 : int; F2 : int } 
type B = { F1 : int; F3 : int } 

// error FS0656: This record contains fields from inconsistent types 
let a1 = { F1 = 1; F2 = 2 } 

// this works 
let a2 = { A.F1 = 1; F2 = 2 } 

我不明白,为什么在一个错误A1的结果。

我可以找到所有的例子,为什么你必须这样做,A2方式假设A和B中的所有字段名称具有相同的名称 - 这当然是模棱两可的,但不应该A和B至少有一个不同的字段时可以区分吗?

也许这只是F#评估的方式,并将类型名称添加到第一个字段当然没有什么大不了的,但我只是好奇。

编辑: 感谢您的回答,帮助我注意到一些相当奇怪的事情:当我第一次评估它时,整个代码段工作正常(ALT + Enter in VS 2010)。

当我第二次尝试评估时,出现错误。

如果没有人能重现此我VS的安装可能borked ...

EDIT2(好吧,时间在这里创建一个帐户,用于编辑抱歉) 感谢wmeyer(和其他人)抽出有时间研究这个问题,并让我意识到我对FSI的工作原理的误解。现在都清理了!

回答

5

只是检查与FSI,此代码的工作

type A = { F1 : int; F2 : int } 
type B = { F1 : int; F3 : int } 
let a1 = { F1 = 1; F2 = 2 } 

也许你有别的东西,这不是在您的文章,导致这种不确定性提及?

3

事实上,它听起来像它应该工作 - 从the spec

如果场labeli不是一个单一的 标识符或初始类型是 变量类型,则场标签 解决通过执行字段标签 分辨率(见§14.1) field-labeli,这导致字段FSeti的集合 。这个 集合中的每个元素都有一个对应的记录类型, 产生一组记录类型 RSeti。的所有RSeti 交点必须一次性记录类型R,和 然后每个场解析为 相应字段R.

只要这意味着作为所有包含这些字段的可能记录的联合标识符解析为只有一种记录类型,那么它是合法的。你使用什么编译器?

6

我不认为你的安装是borked。

这是有道理的代码不适用于第二次评估时。旧型号AB仍然存在,它们只是shadowed
另一方面,字段名称永远不会被遮蔽。 (否则,你永远不能在两个不同的记录中拥有相同的字段名称。)
“所有可能记录的联合”(参见Massif的答案)现在有多个要素:旧的(被遮蔽的)A和新的A

要解决此问题,可以在运行间的F#Interactive上下文菜单中使用“重置会话”。或者将你的代码包装在一个模块中(然后旧的记录类型将不可访问,也不在范围内)。

相关问题