将Clojure向量的内容提取为LazySeq

时间:2014-02-03 15:56:01

标签: clojure lazy-sequences

我使用Clojure的Java API,我有一个通过代码创建的持久向量:

 IPersistentVector vec = PersistentVector.create();

后来填充了值。

我需要将此向量的内容提取为LazySeq。我知道向量的方法seq()会返回ISeq。有没有办法将此ISeq转换为LazySeq

谢谢,

克里斯

2 个答案:

答案 0 :(得分:2)

ISeq是seqs的接口,因此LazySeq也会实现ISeqseq函数类型将其返回提示为ISeq

在向量上调用seq将返回PersistentVector$ChunkedSeq,这是一种不同类型的延迟序列。它的实现是为了逐元素地分摊生产它的成本(我认为它一次评估8个元素)。

如果你真的想要LazySeq,你可以做

(lazy-cat [1 2 3])

但这只会强制逐个元素评估并消除分块行为。

在Java中,这将是:

// once
Var lazyCat = RT.var("clojure.core", "lazy-cat");

// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) lazyCat.invoke(vector);

请注意,它会让我实际将结果转换为LazySeq,因此我在这里使用了接口ISeq没有保证具体类LazySeq是您将来在任何时候实际收到的内容。鉴于此,您可以直接调用seq:

// once
Var seq = RT.var("clojure.core", "seq");

// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) seq.invoke(vector);

通常,总是通过从运行时获取的Vars调用Clojure类并且仅转换为接口,而不是转换为具体类型。这大大降低了从发布到发布的事情将会破坏的可能性。

答案 1 :(得分:1)

我完全没有理由去做这个以及几个不好的事情,但这里是较低的等级。

import clojure.lang.*;

public class Foo {
    public static IFn thunk(final Object x){
           return new AFn(){
               public Object invoke() { return x; } 
           }; 
    }

     public static void main(String[] args) throws Exception {
         PersistentVector vec;
         LazySeq lazySeq;

         vec = PersistentVector.create(1, 2, 3);
         System.out.println(vec);

         lazySeq = new LazySeq(thunk(vec));
         System.out.println(lazySeq);
         System.out.println(RT.printString(lazySeq));
     }
}

输出,例如

[1 2 3]
clojure.lang.LazySeq@7861
(1 2 3)