Enum types
Not the same as a union type
The enum type in F# is the same as the enum type in C#. Its definition is superficially just like that of a union type, but there are many non-obvious differences to be aware of.
Defining enums
To define an enum you use exactly the same syntax as a union type with empty cases, except that you must specify a constant value for each case, and the constants must all be of the same type.
Strings are not allowed, only ints or compatible types such bytes and chars:
Union types require that their cases start with an uppercase letter. This is not required for enums.
Just as with C#, you can use the FlagsAttribute for bit flags:
Constructing enums
Unlike union types, to construct an enum you must always use a qualified name:
You can also cast to and from the underlying int type:
You can even create values that are not on the enumerated list at all.
And, unlike unions, you can use the BCL Enum functions to enumerate and parse values, just as with C#. For example:
Matching enums
To match an enum you must again always use a qualified name:
Both unions and enums will warn if you have not covered all known cases when pattern matching:
One important difference between unions and enums is that can you make the compiler happy about exhaustive pattern matching by listing all the union types.
Not so for enums. It is possible to create an enum not on the predeclared list, and try to match with it, and get a runtime exception, so the compiler will warn you even if you have explicitly listed all the known enums:
The only way to fix this is to add a wildcard to the bottom of the cases, to handle enums outside the predeclared range.
Summary
In general, you should prefer discriminated union types over enums, unless you really need to have an int
value associated with them, or you are writing types that need to be exposed to other .NET languages.
Last updated
Was this helpful?