У меня есть длинная ленивая последовательность, которую я хочу уменьшить и проверить лениво.Как только два последовательных элемента не равны =
(или некоторому другому предикату) друг другу, я хочу прекратить использование списка, который является дорогим для производства.Да, это звучит как take-while
, но читайте дальше.
Я хотел написать что-то простое и элегантное, как это (притворяясь, что every?
работает как reduce
):
(every? = (range 100000000))
Но это не работает лениво и поэтому зависает на бесконечных последовательностях.Я обнаружил, что это работает почти так, как я хотел:
(apply = (range 100000000))
Однако я заметил, что разбиение на последовательности приводило к созданию и тестированию дополнительных ненужных элементов.По крайней мере, я думаю, именно это происходит в следующем фрагменте кода:
;; Displays chunking behavior in groups of four on my system and prints 1 2 3 4
(apply = (map #(do (println %) %) (iterate inc 1)))
;; This prints 0 to 31
(apply = (map #(do (println %) %) (range)))
Я нашел обходной путь, используя take-while
и count
для проверки количества взятых элементов, ноэто довольно громоздко.
Должен ли я вежливо предложить Ричу Хики, чтобы он правильно сделал некоторую комбинацию короткого замыкания reduce
и every?
, или я упускаю какой-то очевидный способ, который уже существует?
РЕДАКТИРОВАТЬ: Два добрых человека опубликовали решения, позволяющие избежать разбиения на ленивые последовательности, но как мне избежать разбиения на части при выполнении apply
, которое, по-видимому, потребляет в группах по четыре из кусочков?
РЕДАКТИРОВАТЬ # 2: Как отмечает Стюарт Сьерра, и я обнаружил, что на самом деле это не куски.Он просто действует как обычно, поэтому я назову это закрытым и дам ему ответ.Я включил небольшую функцию в отдельный ответ, чтобы выполнить уменьшающую часть проблемы для тех, кто заинтересован.