Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created October 21, 2016 00:14
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save khanlou/60c4fd0baa457b7a621a74ee599be867 to your computer and use it in GitHub Desktop.
Save khanlou/60c4fd0baa457b7a621a74ee599be867 to your computer and use it in GitHub Desktop.
A state machine where invalid transitions can't compile
protocol State {}
struct Transition<From: State, To: State> {
let transition: () -> To
}
struct Machine<CurrentState: State> {
var state: CurrentState
func transition<To>(with transition: Transition<CurrentState, To>) -> Machine<To> where To: State {
return Machine<To>(state: transition.transition())
}
}
struct Pending: State {}
struct Loading: State {}
struct Loaded: State {}
struct Failed: State {}
let kickoff = Transition<Pending, Loading>(transition: { return Loading() })
let finishLoading = Transition<Loading, Loaded>(transition: { return Loaded() })
let machine = Machine<Pending>(state: Pending())
let newMachine = machine.transition(with: kickoff) // compiles
newMachine.transition(with: finishLoading)
machine.transition(with: finishLoading) // Cannot convert value of type 'Transition<Loading, Loaded>' to expected argument type 'Transition<Pending, _>'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment