我有一个 F# 程序,可以生成状态列表。我还有一个 Windows 窗体,它使用 GDI+ 来渲染表示屏幕状态的图形。当用户单击表单中的按钮时,应呈现下一个状态。在 C# 中,我将存储一个索引并使用它来获取列表中的下一个状态。我知道我可以创建一个可变变量并在 F# 中执行相同的操作,但这似乎不是正确的方法。
是否有一种方法更适合函数式编程范例,以便在事件触发时从列表中获取下一个值?点击事件的伪代码:
let clicked e =
let state = getNextState
render state
最佳答案
实际上,我认为使用可变变量是完全可以的 - 使用单个可变变量来保持当前状态是 F# 中相当常见的模式。
也就是说,您可以使用 Event.scan
函数对逻辑进行编码。该函数保留状态并允许您在每次事件发生时计算新状态。这是一个最小的演示,它使用它来创建一个按钮,上面有一个数字,每次单击时该数字都会递增:
let frm = Form(Visible=true)
let btn = Button(Text="Click")
frm.Controls.Add(btn)
如您的示例所示,我们有一些初始状态、计算下一个状态的函数以及根据当前状态更新 GUI 的函数:
let initialState = 0
let nextState state = state + 1
let updateForm state = btn.Text <- string state
现在,您可以使用 Event.scan
创建一个新事件,其中包含通过将 nextState
应用于每次点击时的上一个状态来计算的“当前状态”。使用 Event.add
,然后我们在状态更改时调用 updateForm
:
btn.Click
|> Event.scan (fun oldState event -> nextState oldState) initialState
|> Event.add (fun state -> updateForm state)
关于events - 对 F# 中的事件使用react时从列表中获取下一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41923135/