First of all, as several people have mentioned in the comments, the type you have defined is not an Enumeration, it's a Discriminated Union.
Enumerations are effectively just a label given to an integer and, in F#, are declared using this syntax:
type DataType =
|Auction = 1
|Transaction = 2
Using this syntax, you've got a relationship between the value and the associated integer, you can use the integer to get the value of an Enumeration, e.g.
let transaction = enum<DataType>(2) // Transaction
Note that there is nothing stopping you from saying enum<DataType>(3537)
, even though we haven't defined that case.
For more details on Enumerations, see: https://msdn.microsoft.com/en-us/library/dd233216.aspx
Discriminated Unions are much more flexible than Enumerations. Let's take a look at yours:
type DataType =
|Auction
|Transaction
This version is now actually a Standard .NET class with two case identifiers: Auction
and Transaction
. You can think of Auction and Transaction as two type constructors for DataType
.
Discriminated Unions are not restricted to just simple cases, you could store additional data, e.g.
type DataType =
/// An auction with a list of bids
|Auction of Bid list
/// A transaction with some price in GBP
|Transaction of decimal<GBP>
With Disciminated Unions, there is no implicit relationships with integers, if we want to construct a particular case, we have to use the appropriate case identifier.
e.g. let auction = Auction (bidlist)
For more details on Discriminated Unions, see: https://msdn.microsoft.com/en-us/library/dd233226.aspx
In both cases, converting to a specific string for each case can be achieved using pattern matching.
For the Discriminated Union:
let datatypeToString datatype =
match datatype with
|Auction -> "AUCTION"
|Transaction -> "TRANSACTION"
And for the Enumeration:
let datatypeToString datatype =
match datatype with
|DataType.Auction -> "AUCTION"
|DataType.Transaction -> "TRANSACTION"
Notice that when you use Enumerations, F# will give you a compiler warning telling you that pattern matches cases aren't complete. This is because Enumerations are just int
s and there are many int
s besides just 1 and 2, this means that the match cases aren't exhaustive.
I therefore recommend you stick to Discriminated Unions and keep your exhaustive pattern matching.
P.S. If you want to go in the other direction, from string
to DataType
, I recommend using a tryCreateDataType
function which would look something like this:
let tryCreateDataType str =
match str with
|"AUCTION" -> Some Auction
|"TRANSACTION" -> Some Transaction
|_ -> None
This returns an Option
, so it will allow you to safely match against the function being successful or it failing due to an invalid string.