可区分联合用于表示具有多种不同情况的类型,这大致对应于面向对象语言中的类层次结构。例如,一个基类Shape
有两个继承类Circle
and Rectangle
可以这样定义:
type Shape =
| Rectangle of (float * float) * (float * float) // Carries locations of two corners
| Circle of (float * float) * float // Carries center and diameter
您定义受歧视工会的方式并没有真正达到您的预期目的。你的类型Album
, Artist
and Genre
仅代表一个具体类型。
您可以使用记录(就像只有属性的轻量级类)或使用有区别的联合来表示这些单一案例,它对应于单个类,但具有相当轻量级的语法,这是主要的好处。例如:
type Name = string
type Price = decimal
type AlbumId = int
type ArtistId = int
type Artist = Artist of ArtistId * Name
type Album = Album of AlbumId * Name * Price * Artist
要构建一个艺术家和一些专辑,你可以这样写:
let pinkFloyd = Artist(1, "Pink Floyd")
let darkSide = Album(1, "The Dark Side of the Moon", 12.0M, pinkFloyd)
let finalCut = Album(2, "The Final Cut", 11.0M, pinkFloyd)
如果您随后创建一个流派,它将包含专辑列表,可能还包含艺术家列表,因此您可以编写如下内容:
type Genre = Genre of Name * Artist list * Album list
let rock = Genre("Rock", [pinkFloyd], [darkSide; finalCut])
现在的问题是,您实际上想要如何填充类型。您的数据源是什么?如果您要从数据库或 XML 文件加载数据,您可能需要编写一个函数来获取数据源的某些部分并返回Artist
or Album
加载所有专辑和艺术家后,将它们包装在Genre
并将其作为最终结果返回。
PS:回答你的问题有点困难,因为你并没有真正给出你想要做什么的更大的图景。如果您可以给出一个小而具体的示例(包括数据的加载及其使用),那么有人可以帮助您从更实用的角度来看待问题。