什么';在clojure中跟踪以前的值的惯用方法是什么?

什么';在clojure中跟踪以前的值的惯用方法是什么?,clojure,Clojure,我使用for循环来迭代序列,但也许我应该使用一个常规循环并重复?map/reduce在这里有用吗?小心点——在Clojure中,最好不要将看作是循环,而是列表理解——它接受一个集合并返回该集合的修改/过滤版本 通过使用循环和递归,您可以更习惯地(以更功能化的编程风格)执行此操作,如下所示: (defmethod learn [:SARSA :Module] [learner module] (let [samples (get learner :dataset)] (for [

我使用for循环来迭代序列,但也许我应该使用一个常规循环并重复?map/reduce在这里有用吗?

小心点——在Clojure中,最好不要将
看作是循环,而是列表理解——它接受一个集合并返回该集合的修改/过滤版本

通过使用循环和递归,您可以更习惯地(以更功能化的编程风格)执行此操作,如下所示:

(defmethod learn [:SARSA :Module] [learner module] 
  (let [samples (get learner :dataset)]  
    (for [seq samples]
      (let [laststate (atom 0) lastaction (atom 0) lastreward (atom 0)])
       ;;Do some stuff
       ;;Update laststate,lastaction,lastreward

      )

    ))
每次您使用新值迭代
上次状态
上次操作
上次奖励
(如果让[sample(first samples)]
部分确定是否还有样本可供查看——如果没有,则表示您在列表的末尾,
(first’())
将返回
nil
,因此您的结果将以您想要的任何形式返回--请参阅最后一行,我刚刚将它们作为向量返回。如果仍然有样本,我们将第一个绑定到符号
sample
,您可以使用它来更新
最后状态的计算,等等,然后
重复
(下一个示例)
,这是该列表中第一个示例之后的所有内容


编辑:我通常会尽可能地尝试使用map/reduce做一些事情,但是当你试图做一个复杂的循环操作,其中你正在统计和计算一些不同的统计数据时,循环/重现通常是最好的方法。

@DaveYarwood在他的回答中暗指
map
/
reduce
;以下是如何实施它:

(defmethod learn[:SARSA模块][学习者模块]
(减少(fn[[州行动奖励]样本]
做一些事情,为状态/行动/奖励计算新的值
[新状态新动作新奖励])
[0 0 0]
(获取学习者:数据集)))

如果我可以单击两个解决方案,我会的。这也是一个很好的解决方案。谢谢。
循环重现
主要是用于实现高级原语的低级机制。它在客户端代码中的使用几乎从来都不是出于表达性或可读性。主要的动机是性能,但很少是合理的优化关于。我的观点是,有时候,如果你处理的是一个复杂的循环和多个局部变量,那么只使用循环/递归会更容易/更简单。当然,在本例中,在阅读@omiel的解决方案之后,我认为我错了——在本例中,reduce要简单得多。
(defmethod learn [:SARSA Module] [learner module]
  (loop [samples (get learner :dataset)
         last-state 0
         last-action 0
         last-reward 0]
    (if-let [sample (first samples)]
      (recur (next samples) (new-last-state) (new-last-action) (new-last-reward))
      [last-state last-action last-reward])))