Enums in Racket
Our enum type ServerState
has an underlying int
type.
#lang racket
(define-type ServerState
(Int one-of
(StateIdle 0)
(StateConnected 1)
(StateError 2)
(StateRetrying 3)))
The possible values for ServerState
are defined as constants. Racket doesn’t have a direct equivalent of Go’s iota
, but we can enumerate them manually.
(define StateIdle 0)
(define StateConnected 1)
(define StateError 2)
(define StateRetrying 3)
By implementing a function to convert ServerState
values to strings, values of ServerState
can be printed out or converted to strings.
(define state-name
(hash
StateIdle "idle"
StateConnected "connected"
StateError "error"
StateRetrying "retrying"))
(define (state->string s)
(hash-ref state-name s "unknown"))
If we have a value of type int
, we cannot pass it to transition
- the compiler will provide some degree of compile-time type safety.
(define (main)
(let ((ns (transition StateIdle)))
(displayln (state->string ns))
(let ((ns2 (transition ns)))
(displayln (state->string ns2)))))
transition
emulates a state transition for a server; it takes the existing state and returns a new state.
(define (transition s)
(case s
[(StateIdle) StateConnected]
[(StateConnected) StateIdle]
[(StateRetrying) StateIdle]
[(StateError) StateError]
[else (error "unknown state")]))
To run this program, open a Racket REPL or script file and execute the main
function.
(main)
The output of the program will look like this:
connected
idle