Custom account implementation for lazy seq

In the below code example, I am returning a lazy list. What I would like to accomplish when someone calls up a list count is that some kind of arbitrary function is executed instead and returns whatever I like.

(defn my-range [i limit]
  (lazy-seq 
   (when (< i limit)
     (cons i (my-range (inc i) limit)))))

(count (my-range 0 9)) returns whatever

I’m not sure that this should be possible: I looked at reify, but I can’t understand if it can be used in this situation.

+4
source share
1 answer

You can do this, but this is quite a lot of work: you must implement all the interfaces associated with the sequence yourself and delegate most of them to your lazy segment. Here's a sketch:

(defn my-range [i limit]
  (let [ret (lazy-seq 
              (when (< i limit)
                (cons i (my-range (inc i) limit))))]
    (reify
      clojure.lang.Counted
      (count [this] 10)
      clojure.lang.Sequential
      clojure.lang.ISeq
      (first [this] (.first ret))
      (next [this] (.next ret))
      (more [this] (.more ret))
      (cons [this x] (.cons ret x))
      (empty [this] (.empty ret))
      (equiv [this x] (.equiv ret x))
      (seq [this] (.seq ret)))))

, (my-range 1 3) , , 10, .

+4

All Articles