2014-02-03 4 views
2

Я работаю с Java API в Clojure и у меня есть постоянный вектор, который был создан с помощью кода:Распаковка содержимого вектора Clojure как LazySeq

IPersistentVector vec = PersistentVector.create(); 

и позже заполнены значениями.

Мне нужно извлечь содержимое этого вектора как LazySeq. Я понимаю, что метод вектора seq() возвращает ISeq. Есть ли способ конвертировать этот ISeq в LazySeq?

Спасибо,

Chris

+2

Можете ли вы немного расширить * почему * вам нужен экземпляр LazySeq? Библиотека последовательности Clojure разработана таким образом, что вам не нужно ничего знать о базовой структуре данных. – Alex

ответ

2

ISeq представляет собой интерфейс для seqs, так LazySeq реализует ISeq, а также. Тип функции seq намекает на его возврат как ISeq.

Звонок seq на вектор возвратит PersistentVector$ChunkedSeq, который представляет собой разный вид ленивой последовательности. Это реализация, предназначенная для амортизации затрат на ее создание поэтапно (я думаю, что он оценивает 8 элементов за раз iirc).

Если вы действительно хотите 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); 

Обратите внимание, что это дало бы мне tinglies на самом деле привести результат к LazySeq поэтому я использовал интерфейс ISeq в любом случае здесь. Существует no гарантируют, что конкретный класс LazySeq - это то, что вы фактически получите в любой момент в будущем. Учитывая, что вы так же, от вызова SEQ непосредственно:

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

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

В общем, это хорошая идея, чтобы всегда вызывать классы Clojure через Варс, полученные от выполнения и только приведение к интерфейсам, никогда не бетону типы. Это значительно снижает вероятность того, что что-то сломается для вас от выпуска до выпуска.

+0

lazy-cat - это макрос, поэтому это не сработает. Но поскольку, как вы говорите, все это плохая идея, это не такая потеря. – amalloy

+0

Ха, справедливо. –

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] 
[email protected] 
(1 2 3) 
Смежные вопросы