重新实现Clojure的惰性序列

3
我正在尝试重新实现Clojure的lazyseqs作为学习练习,我正在试图弄清楚LazySeq.java中正在发生的事情。

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

这个分支不应该有分块行为,所以我的想法是它每次第一次被调用时都应该调用fn,但我无法弄清楚seq调用做了什么?更具体地说,以下代码行:
s = RT.seq(fn.invoke());
1个回答

1

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(如果我没记错的话)。但我对 Java 不是那么熟练。


谢谢您的解释,但是如果您有一个可以调用的fn对象,您会如何在纯Java中解决这个问题呢? - Hamza Yerlikaya
@hamza-yerlikaya 这就是Java代码的作用。另请参阅编辑。 - kotarak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接