A foundational type in functional programming is the discriminated union, which is a type that can only be one of a set of possible values. Each possible value of a discriminated union is referred to as a union case. With the invariant that discriminated unions can only be one of a set of values, the compiler can do additional checks to make sure your code is correct, in particular, making sure that pattern matches against discriminated union types are exhaustive.
To define a discriminated union, use the
type keyword, followed by
the type’s name, and then each union case separated by a pipe,
|. In a standard deck of cards, a card’s suit
can be represented with the following discriminated union:
> // Discriminated union for a card's suit
|Club;; type Suit = | Heart | Diamond | Spade | Club > let suits = [ Heart; Diamond; Spade; Club ];; val suits : Suit list = [Heart; Diamond; Spade; Club]
You can also optionally associate data with each union case.
To continue the playing-card example, each card can be associated with a
suit, and value cards with an integer and suit pair. (The
int * Suit syntax may look familiar—it is the
type signature of a tuple.)
// Discriminated union for playing cards type PlayingCard = | Ace
of Suit| King
of Suit| Queen
of Suit| Jack
of Suit| ValueCard
of int * Suit// Use a list comprehension to generate a deck of cards let deckOfCards = [ for suit in [ Spade; Club; Heart; Diamond ] do yield Ace(suit) ...