Enums in Haskell

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. Haskell doesn’t have enums in the same way, but we can use Algebraic Data Types (ADTs) to achieve similar functionality.

Our enum type ServerState is defined as an ADT.

data ServerState = StateIdle
                 | StateConnected
                 | StateError
                 | StateRetrying
                 deriving (Show, Enum)

Haskell’s deriving(Enum) automatically generates successive values. deriving(Show) allows us to convert ServerState values to strings.

By defining a function transition, values of ServerState can be manipulated.

transition :: ServerState -> ServerState
transition StateIdle       = StateConnected
transition StateConnected  = StateIdle
transition StateError      = StateError
transition StateRetrying   = StateIdle
transition _               = error "unknown state"

In the transition function, different states are matched using pattern matching. Haskell’s type system provides compile-time type safety, ensuring only valid ServerState values are used.

To run the program, we create a main function.

main :: IO ()
main = do
    let ns = transition StateIdle
    print ns
    let ns2 = transition ns
    print ns2

print is used to output the result.

When run, this will emulate a state transition for a server.

$ runhaskell Enums.hs
StateConnected
StateIdle

In summary, we’ve used Haskell’s ADTs and pattern matching to create and manage enum-like types, ensuring type safety and elegance.