2017-04-20 47 views
1

我想弄清楚如何在F#中使用不可变对象做一个列表。待办事项列表(不一定是F#列表)可能从数据库中提取或从用户输入中收集,或者从XML或JSON等中读取。该部分并不重要。F#待办事项列表使用不可变对象

伪代码:

do for some length of time: 
    for each item in the to do list: 
     if item is ready to do: 
     do item 
     if it worked: 
      remove from the todo list 

    wait a bit before trying again 
report on items that weren't ready or that failed. 

的待办事项清单将是这将有至少一个指令F#记录一些集合(“发送电子邮件”,“启动进程”,“复制文件”, “请求加薪”)以及作为子集合的参数。

这样的事情可以单独使用不可变对象吗?或者我必须使用.NET List或其他可变对象吗?

我不需要完全充​​实工作代码,只是关于如何将这样的事情放在一起的一些想法。

更新:在(半)第一次尝试编码这事

let processtodo list waittime deadline = 
    let rec inner list newlist = 
     match list with 
     | [] when not List.isEmpty newlist -> 
       inner newlist [] 

     | head :: tail when head.isReady-> 
       let res = head.action 
       inner tail (if res = true then tail else list) 

     | head :: tail when not head.isReady -> 
       inner tail list 

     | _ when deadline not passed -> 
      // wait for the waittime 
      inner list 
     | _ -> report on unfinished list 

    inner list [] 

我试过在很多例子看到的典型方式来写这个。我认为这些项目支持“isReady”和“action”方法。我不喜欢的是它不是尾调用递归,所以会消耗每个递归的堆栈空间。

+1

该计划的哪个特定部分你看不到如何处理不可变对象?为什么?你认为是什么问题? –

+0

在for循环中,删除列表项,以便do循环的下一次迭代不会看到它们 – user1443098

+1

而不是考虑如何从待办事项列表中添加/删除指令,请考虑您想要的结果在那个过程之后:一个待办事项列表,没有完成的指示。 '待办事项列表 - >处理每个项目的指示 - >返回没有完成任务的新列表(并使用返回的列表作为新的待办事项列表) –

回答

2

递归和/或延续是将具有可变结构循环的代码转换为不可变结构的典型策略。如果你知道如何编写一个递归的“List.filter”,那么你可能会有一些想法在正确的轨道上。

+0

我正在考虑递归,但卡住了。 (我还更新了伪代码,以表明我想在do-loop尝试之间等待一会儿。)内部循环只能对待办事项列表执行一次迭代。当它结束时,do循环需要等待一会儿(TBD),然后重新运行带有(可能修改的)列表的for循环。\ – user1443098

+0

我第一次尝试更新了帖子。 – user1443098