Дискриминационные объединения используются для представления типов в нескольких различных случаях, что примерно соответствует иерархии классов в объектно-ориентированных языках. Например, базовый класс Shape
с двумя унаследованными классами для Circle
и 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
и 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
или Album
и после загрузки всех альбомов и исполнителей, оберните их внутри Genre
и верните это как конечный результат.
PS: Сложно ответить на ваши вопросы, потому что вы на самом деле не представляете более полную картину того, что вы пытаетесь сделать. Если вы можете привести небольшой, но конкретный пример (включая загрузку данных и их использование), то кто-то может помочь вам взглянуть на проблему с более функциональной точки зрения.