在对F#中的事件作出反应时,将下一个值从列表中取出

时间:2017-01-29 16:27:50

标签: events f#

我有一个生成状态列表的F#程序。我还有一个窗体,它使用GDI +渲染代表屏幕状态的图形。当用户单击表单中的按钮时,应呈现下一个状态。在C#中,我会存储一个索引并使用它来从列表中获取下一个状态。我知道我可以创建一个可变变量并在F#中执行相同的操作,但这似乎不是正确的方法。

有没有一种方法可以更好地融入函数式编程范例,以便在事件被触发时从列表中获取下一个值? click事件的伪代码:

let clicked e =
    let state = getNextState
    render state

1 个答案:

答案 0 :(得分:4)

在实践中,我认为使用可变变量是完全正确的 - 使用单个可变变量来保持当前状态是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创建一个包含&#34;当前状态&#34;的新事件。通过在每次点击时将nextState应用于之前的状态来计算。使用Event.add,我们会在状态发生变化时调用updateForm

btn.Click 
|> Event.scan (fun oldState event -> nextState oldState) initialState
|> Event.add (fun state -> updateForm state)