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
-~----------~----~----~----~------~----~------~--~---

Reply via email to