结合判别联合类型与记录类型

7

我正试图理解区分联合类型和记录类型; 具体来说,是如何将它们组合以实现最大可读性。以下是一个示例 - 假设一个运动队可以拥有积分(包括联赛积分和进球差),或者被暂停参加联赛,在这种情况下它既没有积分也没有进球差。以下是我尝试表达它的方式:

type Points = { LeaguePoints : int; GoalDifference : int }

type TeamState = 
    | CurrentPoints of Points
    | Suspended

type Team = { Name : string; State : TeamState }

let points = { LeaguePoints = 20; GoalDifference = 3 }

let portsmouth = { Name = "Portsmouth"; State = points }

问题出现在最后一行,我说“State = points”。我得到了“表达式应该具有TeamState类型,但这里具有Points类型”的错误。如何解决这个问题?
2个回答

16
为了对pad的回答进行补充,你原始版本未能正常工作的原因是State赋值的类型应该是一个TeamState类型的可辨识联合值。在你的表达式中:
let portsmouth = { Name = "Portsmouth"; State = points }

...points的类型是Points。在pad发布的版本中,表达式CurrentPoints points使用了TeamState的构造函数来创建一个代表CurrentPoints的带标记联合值。联合类型提供给你的另一个选项是Suspended,可以像这样使用:

let portsmouth = { Name = "Portsmouth"; State = CurrentPoints points }
let portsmouth = { Name = "Portsmouth"; State = Suspended }
如果你没有使用构造函数的名字,那么如何构建一个暂停的团队,这将不太清晰!
最后,你也可以将所有内容写在一行上,但这不够易读:
let portsmouth = 
  { Name = "Portsmouth"
    State = CurrentPoints { LeaguePoints = 20; GoalDifference = 3 } }

1
谢谢您的详细解释,Tomas :-) - Kit

6
let portsmouth = { Name = "Portsmouth"; State = CurrentPoints points }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接