Я не знаю ни одного из существующих способов сделать это, возможно, было бы неплохо просмотреть документацию clojure.contrib, чтобы посмотреть, есть ли уже что-то. А пока я посмотрел на ваш пример и немного прояснил его.
(defn report [cnt]
(when (even? cnt)
(println "Done" cnt)))
(defn report-progress []
(let [aseq (range 10)]
(doall (map report (take (count aseq) (iterate inc 1))))
aseq))
Вы движетесь в правильном направлении, хотя этот пример слишком прост. Это дало мне представление о более обобщенной версии вашей функции выполнения отчетов. Эта функция будет принимать функцию, подобную карте, отображаемую функцию, функцию отчета и набор коллекций (или начальное значение и коллекцию для тестирования).
(defn report-progress [m f r & colls]
(let [result (apply m
(fn [& args]
(let [v (apply f args)]
(apply r v args) v))
colls)]
(if (seq? result)
(doall result)
result)))
Секв? часть есть только для использования с уменьшением, которое не
обязательно возвращает последовательность. С помощью этой функции мы можем переписать ваш
Пример как это:
user>
(report-progress
map
(fn [_ v] v)
(fn [result cnt _]
(when (even? cnt)
(println "Done" cnt)))
(iterate inc 1)
(range 10))
Done 2
Done 4
Done 6
Done 8
Done 10
(0 1 2 3 4 5 6 7 8 9)
Проверка функции фильтра:
user>
(report-progress
filter
odd?
(fn [result cnt]
(when (even? cnt)
(println "Done" cnt)))
(range 10))
Done 0
Done 2
Done 4
Done 6
Done 8
(1 3 5 7 9)
И даже функция уменьшения:
user>
(report-progress
reduce
+
(fn [result s v]
(when (even? s)
(println "Done" s)))
2
(repeat 10 1))
Done 2
Done 4
Done 6
Done 8
Done 10
12