5
(defn unfold [step seed]
  (if-let [[val new-seed] (step seed)]
    (cons val (lazy-seq (unfold step new-seed)))
    nil))

示例用法:

(defn fib-step [[x y]] [x [y (+ x y)]])
(take 10 (unfold fib-step [0 1])) ;=> (0 1 1 2 3 5 8 13 21 34)

(defn decreasing [x] (if (neg? x) nil [x (dec x)]))
(unfold decreasing 5) ;=> (5 4 3 2 1 0)

这个或类似的东西是否存在于clojure标准(或常用)库中?如果没有,有什么原因吗?我找到的最接近的是这篇博文:

http://www.matlux.net/blog/2014/05/04/anamorphic-adventure-in-clojure

4

1 回答 1

5

不,unfold没有在 Clojure 中实现。它由 amalloys flatland.useful 库提供,根据 CrossClj 具有广泛的用途。看到您链接的博客文章对该主题进行了相当深入的探索,我怀疑您的问题比直接回答所能满足的要多……您是否想到了一些iterate不足之处?或者对名字或行为iterate不完全的失望?unfold

(defn fib-step [[a b]] [b (+ a b)])
(take 10 (map first (iterate fib-step [0 1])))

(take-while (complement neg?) (iterate dec 5))

我更喜欢使用iterate这些示例,因为iterate它已经是核心的一部分。我可以看到人们更喜欢unfold他们更熟悉的东西。

有许多库提供“应该在核心中的东西”,例如https://weavejester.github.io/medley/medley.core.html在https://crossclj.info/上的快速搜索显示https://github.com/amalloy/useful包含 flatland.useful.seq/unfold,虽然我没有使用过,但它看起来是 Clojure 核心贡献者的一个很好的实现并附带一些其他很酷的东西来启动。

于 2015-12-17T03:15:32.930 回答