F#:存储和映射函数列表

rys*_*ama 3 f# function list map

我在游戏中发生了很多事件.我想控制这些事件发生的时间和顺序.

例如:

事件1:在屏幕上显示N帧的一些文本并播放声音效果

事件2:清除屏幕上的文本

我的解决方案(可能有一个更好的解决方案)是拥有包含事件的函数列表.事件执行其行为然后返回在游戏中发生的下一个事件.我想过使用List.map或List.collect,因为我实际上是在执行某些行为代码时将事件列表映射到新的事件列表.

在上面的示例中,Event1可以由两个函数组成:一个显示文本,另一个播放声音(因此需要列表).显示文本的函数将为N-1帧返回自身的副本,然后它将返回清除文本的Event2.播放声音功能将返回相当于无操作的声音.

如果这是一个很好的解决方案,我可以用C++或C#来做.我的目标是在F#中做同等或更好的解决方案.

cfe*_*ern 5

你的意思是这样的吗?

let myActions =
    [fun () -> printfn "You've woken up a dragon."
     fun () -> printfn "You hit the dragon for 0 points of damage."
     fun () -> printfn "The dragon belches."
     fun () -> printfn "You have died."] 

let actionBuilder actionList = 
    let actions = ref actionList
    fun () ->
        match !actions with
        | [] -> ()
        | h::t -> h(); actions := t
Run Code Online (Sandbox Code Playgroud)

用法(F#interactive):

> let doSomething = actionBuilder myActions;;

val doSomething : (unit -> unit)

> doSomething();;
You've woken up a dragon.
val it : unit = ()
> doSomething();;
You hit the dragon for 0 points of damage.
val it : unit = ()
> doSomething();;
The dragon belches.
val it : unit = ()
> doSomething();;
You have died.
val it : unit = ()
> doSomething();;
val it : unit = ()
> 
Run Code Online (Sandbox Code Playgroud)

**编辑:**如果你想能够添加动作,也许最好制作一个内部使用Queue的动作分配器,因为追加的是带有列表的O(N)和带有队列的O(1):

type actionGenerator(myActions: (unit->unit) list) =
    let Q = new System.Collections.Generic.Queue<_>(Seq.ofList myActions)

    member g.NextAction = 
        fun () -> 
            if Q.Count = 0 then ()
            else Q.Dequeue()()

    member g.AddAction(action) = Q.Enqueue(action)
Run Code Online (Sandbox Code Playgroud)