У меня есть рекурсия с использованием loop
recur
с довольно сложной логикой. Оказывается, я должен делать то же самое в двух ветвях, что должно привести к рекурсии. Я не верю, что могу абстрагировать это, используя функцию из-за ограничений recur, так как я могу это сделать и не иметь дублирующий код. Должен ли я использовать макрос?Не повторяется в рекурсии
код ниже, и повторил код выделен повторяющийся код ЗДЕСЬ
(defn overlapping-sampler [n-samples]
(let [...]
(loop [samples [] cache (zipmap boxes []) n-samples n-samples]
(cond
(zero? n-samples)
samples
:else
(let [box (categorical boxes volumes)
cache-item (peek (cache box))]
(if (nil? cache-item)
; REPEATED CODE HERE
(let [sample (interval-sample (:internals box))
all-boxes (map #(apply (:formula %) sample) boxes)
pos-dominant (max-pred-index true? all-boxes)
pos-box (max-pred-index #(= box %) boxes)]
(if (= pos-dominant pos-box)
(recur (conj samples sample) cache (dec n-samples))
(recur samples
(update-in cache [(nth boxes pos-dominant)]
#(conj % {:from box :sample sample}))
n-samples)))
; Otherwise with prob p=ratio of overlapping region/box, take sample
(if (flip (/ (volume (overlap box (:from cache-item))) (volume box)))
(recur (conj samples (:sample cache-item)) ; I should take the sample
(update-in cache [box]
#(pop %))
(dec n-samples))
(let [sample (gen-until #(interval-sample (:internals box))
#(and (apply (:formula box) %)
(not (apply (:formula (:from cache-item)) %))))
;REPEATED CODE HERE
all-boxes (map #(apply (:formula %) sample) boxes)
pos-dominant (max-pred-index true? all-boxes)
pos-box (max-pred-index #(= box %) boxes)]
(if (= pos-dominant pos-box)
(recur (conj samples sample) cache (dec n-samples))
(recur samples
(update-in cache [(nth boxes pos-dominant)]
#(conj % {:from box :sample sample}))
n-samples))))))))))