懒惰seq的自定义计数实现

时间:2014-10-14 14:16:58

标签: clojure

在下面的示例代码中,我返回一个惰性列表。当有人调用列表时我想要发生的是,某些任意函数被执行而是返回我喜欢的任何内容。

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

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

我不确定这是否可能:我一直在关注reify,但无法弄清楚是否可以在这种情况下使用它。

1 个答案:

答案 0 :(得分:4)

你可以做到这一点,但它需要做很多工作:你必须自己实现所有与序列相关的接口,并将大部分接口委托给懒惰的seq。这是一个草图:

(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的两项序列,这就是你想要的。