Enums in Prolog

Our enum type `ServerState` has an underlying `int` type.

```swift
enum ServerState: Int {
    case idle = 0
    case connected
    case error
    case retrying
}

The possible values for ServerState are defined as constants. Swift automatically assigns successive integer values starting from 0.

By conforming to the CustomStringConvertible protocol, values of ServerState can be converted to String.

extension ServerState: CustomStringConvertible {
    var description: String {
        switch self {
        case .idle:
            return "idle"
        case .connected:
            return "connected"
        case .error:
            return "error"
        case .retrying:
            return "retrying"
        }
    }
}

If we have a value of type Int, we cannot pass it directly to transition without explicitly converting it to the enum type, providing compile-time type safety.

func main() {
    let ns = transition(state: .idle)
    print(ns)
    
    let ns2 = transition(state: ns)
    print(ns2)
}

main()

The transition function emulates a state transition for a server; it takes the existing state and returns a new state.

func transition(state: ServerState) -> ServerState {
    switch state {
    case .idle:
        return .connected
    case .connected, .retrying:
        return .idle
    case .error:
        return .error
    }
}
$ swift run enums.swift
connected
idle

Now that we have implemented a simple enum-based state machine in Swift, we can explore more advanced features of the language.