Regarding your recent edit clarifying what seqn
is doing, these are the two options I'd choose between:
(defn sequence-parser1 [& parsers]
(fn [stream]
(reduce (fn [[res acc-stream] p]
(let [[r stream'] (p acc-stream)]
[(conj res r) stream']))
[[] stream]
parsers)))
(defn sequence-parser2 [& parsers]
(fn [stream]
(loop [[p & rest-parsers] parsers
acc-stream stream
res []]
(if p
(let [[r stream'] (p acc-stream)]
(recur rest-parsers stream' (conj res r)))
[res acc-stream]))))
Both are basically the same code; just a reduction over parsers
. I tend to lean towards using loop
when I have multiple accumulators though, as I find constant pairing/deconstruction in the reducing function to be messy.
If you didn't need to accumulate a stream
while iterating the parsers, this could be done very succinctly using map
, but alas, that wouldn't work here unfortunately.