(defn unfold [step seed]
(if-let [[val new-seed] (step seed)]
(cons val (lazy-seq (unfold step new-seed)))
nil))
Example usage:
(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)
Does this or something like it exist in clojure standard (or commonly used) libs? If not, is there a reason why? The closest I've found is this blog post:
http://www.matlux.net/blog/2014/05/04/anamorphic-adventure-in-clojure
No, unfold
is not implemented in Clojure. It is provided by amalloys flatland.useful library, which has wide usage according to CrossClj. Seeing as the blog post you linked provides quite a deep exploration of the subject, I suspect there is more to your question than a direct answer can satisfy... Do you have some scenario in mind where iterate
is inadequate? Or disappointed that iterate
is not quite unfold
in name or behavior?
(defn fib-step [[a b]] [b (+ a b)])
(take 10 (map first (iterate fib-step [0 1])))
(take-while (complement neg?) (iterate dec 5))
I prefer to use iterate
for these examples because iterate
is part of core already. I can see people preferring unfold
if that is more familiar to them.
There are many libraries that provide "things that should have been in core" such as https://weavejester.github.io/medley/medley.core.html. A quick search on https://crossclj.info/ reveals https://github.com/amalloy/useful contains flatland.useful.seq/unfold, which though I have not used looks to be a great implementation by a Clojure core contributor and comes with some other cool stuff to boot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With