events - 对 F# 中的事件使用react时从列表中获取下一个值

标签 events f#

我有一个 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/

相关文章:

f# - 避免堆栈溢出(使用 F# 无限序列)

并行使用时随机数生成器会中断

Javascript检测下拉列表何时关闭

linux - C(linux平台)中基于事件的通信的最佳机制

javascript - 如何在不将事件监听器放在 HTML 标签中的情况下获取事件目标/this?

c# - LinkLabel.Click 和 LinkLabel.LinkClicked 事件之间的区别?

events - 什么时候使用事件?

macos - 在 Mac 上以 32 位模式运行交互式 F#

f# - List.partition 是否保证保持顺序?

f# - F# 中对象/记录的无点样式