Discriminated unions in F# offer a a way to define types which may hold any number of different data types. Their functionality is similar to C++ unions or VB variants, but with the additional benefit of being type safe.
Converting to and from strings with Reflection
Sometimes it's necessary to convert a Discriminated Union to and from a string:
Type information does not need to be included in the cases of a discriminated union. By omitting type information you can create a union that simply represents a set of choices, similar to an enum.
Naming elements of tuples within discriminated unions
When defining discriminated unions you can name elements of tuple types and use these names during pattern matching.
Additionally naming the elements of discriminated unions improves readability of the code and interoperability with C# - provided names will be used for properties' names and constructors' parameters. Default generated names in interop code are "Item", "Item1", "Item2"...
Recursive discriminated unions
Discriminated unions can be recursive, that is they can refer to themselves in their definition. The prime example here is a tree:
As an example, let's define the following tree:
We can define this tree using our recursive discriminated union as follows:
Iterating over the tree is then just a matter of pattern matching:
Mutually dependent recursive types
One way to achieve recursion is to have nested mutually dependent types.
Defining a record type directly inside a discriminated union is deprecated:
You can use the and keyword to chain mutually dependent definitions:
With the RequireQualifiedAccess attribute, union cases must be referred to as MyUnion.MyCase instead of just MyCase. This prevents name collisions in the enclosing namespace or module:
If, for example, System has been opened, Single refers to System.Single. There is no collision with the union case Requirements.Single.
Single case discriminated union
A single case discriminated union is like any other discriminated union except that it only has one case.
It is useful for enforcing type safety and commonly used in F# as opposed to C# and Java where creating new types comes with more overhead.
The following two alternative type definitions result in the same single-case discriminated union being declared:
Using Single-case Discriminated Unions as Records
Sometimes it is useful to create union types with only one case to implement record-like types:
These become very useful because they can be decomposed via pattern matching in the same way as tuple arguments can:
This modified text is an extract of the original Stack Overflow Documentation created by following contributors and released under CC BY-SA 3.0