Recursion 如何在F#中使用函数表示状态来获得工作状态机?
我正试图在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
我有一家国营工厂:
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案例中缺少的关于类型推断的什么内容呢?