我编写了一个函数(如下所列),该函数返回一个函数,该函数从注释中定义的无限集中返回 n 个项目。
; Returns a function which in turn returns a vector of 'n' items, with init-val being the 'middle' value,
; Values to the 'right' of init-val being 'step' added to the (previously) last value, and items 'left' of
; 'init-val' being 'step' subtracted from the (previously) first value in the list.
(defn range-right-left [init-val step]
(fn [n] ; produce a vector containing 'n' items
(loop [Vector (cond (zero? n) []
(pos? n) [init-val]
:else nil)]
(if (or (= (count Vector) n) (nil? Vector)) Vector ; base case(s)
(recur
(if (odd? (count Vector))
(conj Vector (+ (last Vector) step)) ; add 'step' to the last element of the vector and place it on the back of the vector
(vec (cons (- (first Vector) step) Vector)))))))) ;else if Vector contains an even number of items, subtract step from the first item in the vector and place it on front of the resulting collection (converting to vector)
为了阐明函数的行为,我将包含测试代码(全部通过)。
(deftest range-right-left-test
(is (= nil ((range-right-left 7 3) -1)))
(is (= [] ((range-right-left 7 3) 0)))
(is (= [7] ((range-right-left 7 3) 1)))
(is (= [7 10] ((range-right-left 7 3) 2)))
(is (= [4 7 10] ((range-right-left 7 3) 3)))
(is (= [4 7 10 13] ((range-right-left 7 3) 4)))
(is (= [1 4 7 10 13] ((range-right-left 7 3) 5))))
不过,我真正想要的是让'range-right-left'返回一个惰性序列而不是一个函数。换句话说,而不是这样做:
((range-right-left 7 3) 3)
我希望能够做到:
(take 3 (range-right-left 7 3))
惰性序列严格从左到右增长似乎是默认行为。我试图开发一个可以双向增长的惰性序列,但无济于事。我非常感谢这样做的建议。