Recursion 如何在F#中使用函数表示状态来获得工作状态机?

Recursion 如何在F#中使用函数表示状态来获得工作状态机?,recursion,f#,state-machine,mutual-recursion,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

我正试图在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
我用它来创建两个相互递归的状态:

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
let rec pongState()=createState控制台.ReadLine“转到ping”pingState
和pingState=createState Console.ReadLine“转到pong”(pongState())
[]
让主argv=
平州()
0
调用
pingState()
并输入“转到乒乓球”时,状态切换为乒乓球。但是当调用输入“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)
#nowarn“40”
取消有关检查递归定义的对象的初始化合理性的警告,下一个状态函数的不同类型,否则编译器会抱怨将值作为其定义的一部分进行计算,和状态上多余的类型注释,因为FSI抱怨它们被推断为泛型。很多投诉;)


至于以不同的方式建模,我想我会把它包装成一个类型,而不是只使用函数,这看起来更自然。不过,我想这里的重点是使用函数。

您的示例没有编译-它给了我“和pingState”上的值限制错误,这很奇怪;我在fsx文件中得到了相同的编译错误,但在fs文件中没有(在上面的示例中添加了程序代码)谢谢!在fs文件中,上述方法也可以在不显式指定pongState和pingState的返回类型的情况下工作,不知道fs和fsx之间的区别,在fs文件中,有足够的上下文来推断这些状态的具体类型。在fsi中尝试东西时,情况往往不是这样。如果您稍后在fsx中定义了一个使用这些状态的函数,以便可以从中推断类型,那么您也可以在fsx中删除注释。我明白了,但是在fs上下文中,fsi案例中缺少的关于类型推断的什么内容呢?