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 π
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
Ticket
previous example:Senior of int
vsChild of age: int
Distinguish between two fields of the same type β See example below:
Instanciation
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
CustomerId
to a function waiting for anOrderId
Prevents Primitive Obsession at a minimal cost
Trap β οΈ
OrderId orderId
looks 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.
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?