Как преобразовать ленивую последовательность в не ленивую в Clojure
Я попытался сделать следующее в Clojure, ожидая, что будет возвращен класс не ленивых последовательностей:
(.getClass (doall (take 3 (repeatedly rand))))
Тем не менее, это все еще возвращает clojure.lang.LazySeq
, Я думаю, что doall
оценивает всю последовательность, но возвращает исходную последовательность, так как она все еще полезна для запоминания.
Так, каково идиоматическое средство создания не ленивой последовательности от ленивого?
5 ответов
Доал это все, что вам нужно. Тот факт, что seq имеет тип LazySeq, не означает, что он ожидает оценки. Ленивые seqs кэшируют свои результаты, поэтому все, что вам нужно сделать, - это пройти ленивый seq один раз (как это делает doall), чтобы форсировать все это, и, таким образом, сделать его не ленивым. seq не заставляет оценивать всю коллекцию.
Это в некоторой степени вопрос таксономии. ленивая последовательность - это всего лишь один тип последовательности, такой как список, вектор или карта. Поэтому ответ, конечно, "это зависит от того, какой тип не ленивой последовательности вы хотите получить:
Выберите из:
- бывшая ленивая (полностью оцененная) ленивая последовательность
(doall ... )
- список для последовательного доступа
(apply list (my-lazy-seq)) OR (into () ...)
- вектор для последующего произвольного доступа
(vec (my-lazy-seq))
- карта или набор, если у вас есть какое-то специальное назначение.
Вы можете использовать любой тип последовательности, наиболее соответствующий вашим потребностям.
Этот богатый парень, кажется, знает свое недоразумение и абсолютно прав.
Но я думаю, что этот фрагмент кода, используя ваш пример, может быть полезным дополнением к этому вопросу:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
Действительно тип не изменился, но реализация
Я наткнулся на этот пост в блоге о doall
не быть рекурсивным Для этого я нашел первый комментарий в посте сделал свое дело. Что-то вроде:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
Я нашел это полезным в модульном тесте, где я хотел форсировать оценку некоторых вложенных приложений map
форсировать состояние ошибки.