Search code examples
f#enumsdiscriminated-union

Enum vs non-member discriminated union


I've just noticed that there's only a little difference in declaring a non-member discriminated union:

type Color =
    | Red
    | Green
    | Blue

and declaring an enum:

type Color =
    | Red = 0 
    | Green = 1
    | Blue = 2

What are their main differences in terms of performance, usage, etc? Do you have suggestions when to use what?


Solution

  • Enum are stucts and are therefore allocated on the stack, while discriminated unions are references types so are heap allocated. So, you would expect DU to be slightly less performant that enums, though in reality you'll probably never notice this difference.

    More importantly a discriminated union can only ever be one of the types declared, where as enums are really just an integer, so you could cast an integer that isn't a member of the enum to the enum type. This means that when pattern matching the compiler can assert that the pattern matching is complete when you've covered all the cases for a DU, but for an enum you must always put in a default catch all the rest case, i.e for an enum you'll always need pattern matching like:

    match enumColor with
    | Red -> 1 
    | Green -> 2
    | Blue -> 3
    | _ -> failwith "not an enum member"
    

    where as the last case would not be necessary with an DU.

    One final point, as enums are natively supported in both C# and VB.NET, were as DUs are not, enums are often a better choice when creating a public API for consumption by other languages.