Unions
A.k.a. Discriminated Unions (DU)
Key points
Exact term: Discriminated Union (DU)
Sum type: represents an OR, a choice between several Cases
Same principle as for an
enum, but on steroids πͺ
Each case must have a Tag (a.k.a Label, Discriminator) -- in
PascalCaseβEach case may contain data
As Tuple: its elements can be named -- in camelCase π
type Ticket =
| Adult // no data -> β singleton stateless
| Senior of int // holds an 'int' (w/o more precision)
| Child of age: int // holds an 'int' named 'age'
| Family of Ticket list // holds a list of tickets
// recursive type by default (no 'rec' keyword)Cases naming
Cases can be used without qualification: Int32 vs IntOrBool.Int32
Qualification can be forced with RequireQualifiedAccess attribute:
β’ Cases using common terms (e.g. None) β to avoid name collision
β’ Cases names are designed to read better/more explicitly with qualification
Cases must be named in PascalCase β
β’ Since F# 7.0, camelCase is allowed for RequireQualifiedAccess unions π‘
Field labels
Helpful for:
Adding meaning to a primitive type β See
Ticketprevious example:Senior of intvsChild of age: intDistinguish between two fields of the same type β See example below:
Instantiation
Case β constructor β Function called with any case data
Name conflict
When 2 unions have tags with the same name β Qualify the tag with the union name
Unions: get the data out
Only via pattern matching.
Matching a union type is exhaustive.
Single-case unions
Unions with a single case encapsulating a type (usually primitive)
Benefits π
Ensures type safety unlike simple type alias β Impossible to pass a
CustomerIdto a function waiting for anOrderIdPrevents Primitive Obsession at a minimal cost
Trap β οΈ
OrderId orderIdlooks like C# parameter definition
Enum style unions
All cases are empty = devoid of data
β β .NET enum based on numeric values π
Instantiation and pattern matching are done just with the Case.
β The Case is no longer a function but a singleton value.
π βEnumβ style unions | F# for fun and profit
Unions .Is* properties
The compiler generates .Is{Case} properties for each case in a union
Before Fβ― 9: not accessible + we cannot add them manually π
Since Fβ― 9: accessible π
Last updated
Was this helpful?