A neater way is with a list comprehension: work my way down the sequence with (drop ...) until the end (no more (seq ...)) and use these numbers to (take...) sections from the start of the list:
(defn heads [s]
(for [n (range) :while (seq (drop n s))]
(take (inc n) s)))
So if I go
user=> (def x '(1 2 3 4 5 6 7 8))
#'user/x
Then I get the initial sections of increasing length:
user=> (heads x)
((1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5) (1 2 3 4 5 6) (1 2 3 4 5 6 7) (1 2 3 4 5 6 7 8))
And it's lazy - I can pass (range) as an argument:
user=> (take 8 (heads (range)))
((0) (0 1) (0 1 2) (0 1 2 3) (0 1 2 3 4) (0 1 2 3 4 5) (0 1 2 3 4 5 6) (0 1 2 3 4 5 6 7))
Now I can make the function that does successively greater reductions like so:
(defn myreduce [f s]
(map #(reduce f %) (heads s)))
For example:
user=> (reduce + x)
36
user=> (myreduce + x)
(1 3 6 10 15 21 28 36)
user=> (reduce * x)
40320
user=> (myreduce * x)
(1 2 6 24 120 720 5040 40320)