Created
February 1, 2011 08:25
-
-
Save amalloy/805583 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn unfold | |
"Next and done? are functions that operate on a seed. next should | |
return a pair, [value new-seed]; the value half of the pair is | |
inserted into the resulting list, while the new-seed is used to | |
continue unfolding. Notably, the value is never passed as an | |
argument to either next or done?." | |
[next done? seed] | |
((fn unfold* | |
[seed] | |
(lazy-seq | |
(when-not (done? seed) | |
(let [[value new-seed] (next seed)] | |
(cons value | |
(unfold* new-seed)))))) | |
seed)) | |
;; alternate implementation, using a simple-laziness macro. better? | |
(defmacro simple-laziness [bindings & body] | |
(let [inner-fn 'continue | |
names (take-nth 2 bindings) | |
values (take-nth 2 (rest bindings))] | |
`((fn ~inner-fn | |
~(vec names) | |
(lazy-seq | |
~@body)) | |
~@values))) | |
(defn unfold2 | |
([next seed] | |
(unfold next (constantly false) seed)) | |
([next done? seed] | |
(simple-laziness [seed seed] | |
(when-not (done? seed) | |
(let [[value new-seed] (next seed)] | |
(cons value | |
(continue new-seed))))))) | |
(defn fibs [] | |
(unfold (fn [[a b]] [a [b (+ a b)]]) (constantly false) [0 1])) | |
(defn rand-poll [num coll] | |
(unfold (fn [[remaining items]] | |
(let [idx (rand-int (count items))] | |
[(items idx) ; value | |
[(dec remaining) | |
(subvec (assoc items idx (items 0)) ; new seed-vector | |
1)]])) ; numbers left | |
(comp zero? first) | |
[num (vec coll)])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment