I have an enumeration in F#, like this:
type Creature =
| SmallCreature = 0
| MediumCreature = 1
| GiantCreature = 2
| HumongousCreature = 3
| CreatureOfNondescriptSize = 4
I do not like manually typing out numbers, and I want to easily insert more items in the enumeration later without having to shift the numbers.
I tried this
type Creature =
| SmallCreature
| MediumCreature
| GiantCreature
| HumongousCreature
| CreatureOfNondescriptSize
but it caused an error The type 'Creature' is not a CLI enum type later in the program
let input = Int32.Parse(Console.ReadLine())
let output = match EnumOfValue<int, Creature>(input) with // <---Error occurs here
| Creature.SmallCreature -> "Rat"
| Creature.MediumCreature -> "Dog"
| Creature.GiantCreature -> "Elephant"
| Creature.HumongousCreature -> "Whale"
| Creature.CreatureOfNondescriptSize -> "Jon Skeet"
| _ -> "Unacceptably Hideous Monstrosity"
Console.WriteLine(output)
Console.WriteLine()
Console.WriteLine("Press any key to exit...")
Console.Read() |> ignore
How can I define an enumeration without manually assigning number values to each item?
Unfortunately, you can’t. Are the numeric values important? If so, it somewhat escapes the intended use of enums (flags aside). You might consider a class or discriminated union in that case.
Your second example is, in fact, a discriminated union. But your later use of
EnumOfValue, which expects an enum, is causing the error.Another option is to store the enum to number mapping in a dictionary and replace the pattern matching with a dictionary lookup. Then, the numeric value of the enum would be irrelevant.
I agree that manually managing enum values is burdensome. I hope it’s addressed in a future version.