Skip to content

Instantly share code, notes, and snippets.

@taimila
Created May 11, 2016 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save taimila/0434e4f74e4437d22247a1290583db0c to your computer and use it in GitHub Desktop.
Save taimila/0434e4f74e4437d22247a1290583db0c to your computer and use it in GitHub Desktop.
Dynamic recursive API in F#
[<AutoOpen>]
module StateMachine =
type State =
| StateA
| StateB
| StateC
| StateD
| End
type Transition =
{ TargetState: State
Continuation: unit -> TransitionResult }
and TransitionResult =
{ CurrentState: State
Transitions: Transition list }
type Actor =
{ DecideTransition: TransitionResult -> Transition }
let transitions = function
| StateA -> [StateB; StateC; StateD]
| StateB -> [StateA]
| StateC -> [StateB; End]
| StateD -> [StateC; StateD]
| End -> []
let rec transitionsOf state =
[for targetState in state |> transitions do
yield { TargetState = targetState
Continuation = fun () ->
{ CurrentState = targetState
Transitions = transitionsOf targetState }}]
let start =
{ CurrentState = StateA
Transitions = transitionsOf StateA }
[<AutoOpen>]
module Actor =
let random = System.Random ()
let decideTransition result =
let randomIndex = random.Next(result.Transitions.Length)
result.Transitions |> List.item randomIndex
let actor = { DecideTransition = decideTransition }
module Engine =
let runWith actor =
let rec loop result =
if result.CurrentState = End then
()
else
let nextTransition = actor.DecideTransition result
printfn "Next: %A" nextTransition.TargetState
nextTransition.Continuation () |> loop
start |> loop
Engine.runWith actor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment