Enums in OCaml
Enumerated types (enums) are a special case of sum types. An enum is a type that has a fixed number of possible values, each with a distinct name. The target language doesn’t have an enum type as a distinct language feature, but enums are simple to implement using existing language idioms.
Our enum type ServerState has an underlying int type.
type server_state =
| StateIdle
| StateConnected
| StateError
| StateRetryingTo map the enum values to their string representations, we can define a function.
let state_name = function
| StateIdle -> "idle"
| StateConnected -> "connected"
| StateError -> "error"
| StateRetrying -> "retrying"By implementing a function similar to the fmt.Stringer interface, values of server_state can be printed out or converted to strings.
let string_of_server_state ss = state_name ssIf we have a value of type int, we cannot pass it to transition - the compiler will complain about type mismatch. This provides some degree of compile-time type safety for enums.
let transition = function
| StateIdle -> StateConnected
| StateConnected
| StateRetrying -> StateIdle
| StateError -> StateError
| _ -> failwith "unknown state"Here’s the main function to emulate the state transitions and print the results.
let () =
let ns = transition StateIdle in
Printf.printf "%s\n" (string_of_server_state ns);
let ns2 = transition ns in
Printf.printf "%s\n" (string_of_server_state ns2)The transition function emulates a state transition for a server; it takes the existing state and returns a new state.
Suppose we check some predicates here to determine the next state…
$ dune exec ./enums.exe
connected
idleNow that we understand how to define and use enums in OCaml, let’s learn more about the language.