How to get a working state machine in F # using functions to represent states?

I am trying to create a simple state machine in F #, but the problem is getting two states with circular dependencies. I have this factory state:

open System
let createState produceInput stateSwitchRule nextState = 
    let rec stateFunc() = 
        match produceInput() with
        | x when x = stateSwitchRule -> printfn "%s" "Switching state"; nextState()
        | _  -> printfn "%s" "Bad input. Try again"; stateFunc()
    stateFunc

which I use to create two mutually recursive states:

let rec pongState() = createState Console.ReadLine "go to ping" pingState
      and pingState = createState Console.ReadLine "go to pong" (pongState())

[<EntryPoint>]
let main argv = 
    pingState()
    0

When you call pingState()and enter "go to pong", the state switches to pong. But when invoking the "go to ping" input, a null reference exception is thrown.
Is there anyway around this with the chosen approach, or should I model it differently?

+4
source share
1 answer

This is what I did:

#nowarn "40"

open System

let createState produceInput stateSwitchRule nextState = 
    let rec stateFunc () = 
        match produceInput() with
        | x when x = stateSwitchRule -> printfn "%s" "Switching state"; (nextState()) ()
        | _  -> printfn "%s" "Bad input. Try again"; stateFunc()
    stateFunc

let rec pongState : unit -> (unit -> string) = createState Console.ReadLine "go to ping" (fun () -> pingState)
    and pingState : unit -> (unit -> string) = createState Console.ReadLine "go to pong" (fun () -> pongState)

#nowarn "40", , nextState, , , FSI , . ;)

- - , , . , .

+3

All Articles