You are previewing Programming F#.

Programming F#

Cover of Programming F# by Chris Smith Published by O'Reilly Media, Inc.
O'Reilly logo

Discriminated Unions

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
type Suit =
    | Heart
    | Diamond
    | Spade
    | 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) ...

The best content for your career. Discover unlimited learning on demand for around $1/day.