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

List F#:存储和映射函数列表,list,function,f#,map,List,Function,F#,Map,我在一场比赛中有很多事件发生。我想控制这些事件发生的时间和顺序 例如: 事件1:在屏幕上显示N帧文本并播放音效 事件2:清除屏幕上的文本 我的解决方案(也许有更好的解决方案)是有一个包含事件的函数列表。事件执行其行为,然后返回游戏中发生的下一个事件。我考虑使用List.map或List.collect,因为我本质上是在执行一些行为代码时将一个事件列表映射到一个新的事件列表 在上面的示例中,Event1可以由两个函数组成:一个显示文本,另一个播放声音(因此需要列表)。显示文本的函数将返回N-1帧的

我在一场比赛中有很多事件发生。我想控制这些事件发生的时间和顺序

例如:

事件1:在屏幕上显示N帧文本并播放音效

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

我的解决方案(也许有更好的解决方案)是有一个包含事件的函数列表。事件执行其行为,然后返回游戏中发生的下一个事件。我考虑使用List.map或List.collect,因为我本质上是在执行一些行为代码时将一个事件列表映射到一个新的事件列表

在上面的示例中,Event1可以由两个函数组成:一个显示文本,另一个播放声音(因此需要列表)。显示文本的函数将返回N-1帧的自身副本,然后返回清除文本的Event2。play sound函数将返回相当于no-op的值


如果这是一个好的解决方案,我可能会在C++或C语言中完成。我的目标是在F#中实现一个同等或更好的解决方案。

不太确定您在这里想要实现什么。。。仔细想想你要找的确切类型可能会有帮助。听起来您可能想通过应用第一个函数将
(unit->(unit->unit))列表映射到
(unit->unit)列表。如果是这样,您可以这样做:

let l = [(fun () -> (fun () -> printfn "first nested fn")); (fun () -> (fun () -> printfn "second nested fn"))]
let l' = List.map (fun f -> f()) l

如果您正在寻找一种语法来声明列表类型,那么以下是一种方法:

List<`a->`b>
列表'b>
这假设函数只接受一个参数

但是,您正试图找出类型的语法,这一事实本身就暗示您仍然在关注这个问题,就好像您在用过程语言编码一样


“功能性”的方法是集中精力于生成列表的逻辑,让编译器根据代码推断类型。看起来,您正试图以一种非常复杂的方式来做某事。这有时是必要的,但通常不是


既然你在问这个问题,我想你在命令式语言方面有更多的经验。您的问题的真正解决方案似乎与函数列表完全不同。

我已经读了您的问题两遍,但仍然不确定我是否完全理解您的要求。但据我所知,您的“事件”不一定按照它们在“列表”中出现的顺序被调用。如果是这种情况,你并不真的想要一个F#列表,你需要某种形式的查找

现在,另一个问题是,对于一个活动来说,确定接下来应该做什么是否真的是一个好主意?这相当于一次性地硬编码您的功能,不是吗

编辑

我在一篇评论中看到,你说你想“将函数调用链接在一起”

一个接一个地写怎么样?毕竟我们不在Haskell,F#会按你写的顺序解雇他们

如果你想更实用一点,你可以使用continuations——每个函数都有一个额外的参数,这是下一个要执行的函数。几乎是一元的(我相信),只是在你的例子中,它们似乎是动作,所以没有值可以从一个函数串到下一个函数


不确定这是否有帮助:从这里答案的多样性来看,我认为你必须尝试重新表述你的问题。

你是指这样的问题吗

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
用法(F#交互式):

**编辑:**如果您希望能够添加操作,可能最好制作一个内部使用队列的操作分发器,因为附加是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)
类型actionGenerator(myActions:(单位->单位)列表)=
设Q=new System.Collections.Generic.Queue(Seq.ofList myActions)
成员g.NextAction=
乐趣()->
如果Q.Count=0,则()
else Q.Dequeue()()
成员g.AddAction(action)=Q.Enqueue(action)

我的目标是将函数调用链接在一起。例如,函数“foo”将返回下一个要调用的函数“bar”。您试图用函数列表解决什么问题?我已更改了在解决方案空间中定义的原始问题;不是问题空间。我希望这能把事情弄清楚。回答得好,把精力放在一个模棱两可的问题上+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)