Chr*_*ian 5 recursion f# state-machine mutual-recursion
我正在尝试在F#中创建一个简单的状态机,但是无法使用循环依赖的两个状态来工作.
我有这个州工厂:
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
Run Code Online (Sandbox Code Playgroud)
我用它来创建两个相互递归的状态:
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
Run Code Online (Sandbox Code Playgroud)
当调用pingState()并输入"go to pong"时,状态切换为pong.但是当调用输入"go to ping"时,抛出了一个空引用异常.
无论如何,选择的方法是否存在?或者我应该以不同的方式对其进行建模?
这就是我所做的:
#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)
Run Code Online (Sandbox Code Playgroud)
#nowarn "40"抑制有关检查递归定义对象的初始化健全性、nextState 函数的不同类型的警告,否则编译器会抱怨一个值被评估为其定义的一部分,以及状态上多余的类型注释,因为 FSI 抱怨它们被推断为是通用的。很多投诉;)
至于以不同的方式对其进行建模 - 我认为我会将其包装在一种类型中而不是仅使用函数,这看起来更自然。我想使用函数就是这里的重点。