我正在尝试将Clojures lazyseqs重新实现为学习活动,我试图弄清LazySeq.java中发生了什么,

https://github.com/richhickey/clojure/blob/20090320/src/jvm/clojure/lang/LazySeq.java

该分支假定没有分块行为,因此我的想法是假定每次第一次调用时都调用fn,但是我不知道seq调用有什么作用?更具体而言,

s = RT.seq(fn.invoke());

最佳答案

lazy-seq宏的主体放入函数中。当需要使用主体生成的序列时,它只是调用该函数来执行主体。您可以通过以下方式或多或少地重新实现lazy-seq

(defn simple-lazy-seq*
  [seq-producing-fn]
  (reify
    clojure.lang.Sequential
    clojure.lang.Seqable
    (seq [this] (seq (seq-producing-fn)))))

(defmacro simple-lazy-seq
  [& body]
  `(simple-lazy-seq* (fn [] ~@body)))


来自核心的lazy-seq还提供了ISeq接口,但这不是严格必需的。

编辑:用纯Java做事。

static Seqable lazy_seq(IFn seq_generating_fn) {
    return new Seqable() {
        ISeq seq() {
            return RT.seq(seq_generating_fn.invoke());
        }
    }
}

YourClass.lazy_seq(new IFn() {
    Object invoke() {
        return thing.returning_the_seq();
    }
});


我不确定我是否正确理解了语法细节,但是应该很接近。如您所见,这里有一些局限性。例如。 thing必须是final IIRC。但是我不太熟练使用Java。

关于clojure - 重新实现Clojure的懒惰序列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5923177/

10-12 18:06