如何在Clojure中迭代直到固定点?

3

我经常遇到这样的情况:我的代码看起来像这样:

(iterate improve x)

我正在寻找第一个不再比上一个改进的值。无论是 filter 还是 take-while 都没有明显的解决方案。然而,我不愿意写出以下内容:

(loop [current x
       next (improve x)]
  (if (= current next)
    current
    (recur next (improve next))))

或者:

(let [improvements (iterate improve x)]
  (->> (map vector improvements (rest improvements))
    (filter (partial apply =))
    (ffirst)))

因为在某个阶段,这变得重复了,而且固定点迭代是如此基础的任务,肯定有某种库支持存在,对吧?

2个回答

11

您可以使用reducereduced在必要时停止。 reduced会将参数包装在一个特殊对象中,reduce被设计为查找该对象并立即停止处理,返回包装的值。

(def vals (iterate improve x))

(reduce #(if (= %1 %2) (reduced %1) %2) vals)

2
您可以使用 drop-while 然后 first
(defn still-improving? [[x y]]
  ...)

(->> st
     (iterate transition)
     (partition 2 1)
     (drop-while still-improving?)
     ffirst)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接