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

How do I iterate until a fixed point in Clojure?

我的代码经常处于这样的位置:

(iterate improve x)

我正在寻找第一个不再比以前有所改进的值。 filtertake-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)))

因为在某些时候这会变得重复,而且定点迭代肯定是一项基本任务,所以必须在某处提供某种库支持,对吗?

您可以使用 drop-while 然后 first:

(defn still-improving? [[x y]]
  ...)

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

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

(def vals (iterate improve x))

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