On Jun 13, 4:17 pm, Laurent PETIT <[email protected]> wrote:
> So it really seems to me that the missing abstraction, here, is being
> able to do a reduce over the list of pixels, and being able, from the
> reduction function, to quit the reduction early.
A lazy right fold[1] allows short-circuiting, so here's one attempt:
(defn foldr
"Implements a lazy right fold of the function f on coll. f should be
a function of two arguments: the next element to be consumed, and a
function which returns the result of folding the rest of the list.
The reduction starts at the end of the list by calling f with the
last element and val."
[f val coll]
(if-let [s (seq coll)]
(f (first s) (fn [] (foldr f val (rest s))))
val))
(defn interesting? [pixels c]
(let [f (fn [pixel counter] (if (< pixel c) (inc (counter)) 0))]
(foldr f 0 pixels)))
(interesting? (iterate inc 0) 10)
=> 10
The need to exlictly call the lazy thunk passed as the second argument
feels a little weird, but it does give us a lazy "right reduce" that
can short-circuit the reduction when it's done.
Here's a lazy filter function implemented using foldr:
(defn foldr-filter [pred coll]
(let [f (fn [x accum]
(if (pred x)
(cons x (accum))
nil))]
(foldr f nil coll)))
(take 20 (foldr-filter (fn [x] (< x 10)) (iterate inc 0)))
=> (0 1 2 3 4 5 6 7 8 9)
Cheers,
-Sudish
[1]
http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29#Evaluation_order_considerations
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---