コメントで定義されているように、無限セットから 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))
左から右に厳密に成長するのは、遅延シーケンスのデフォルトの動作のようです。双方向に成長できるレイジー seq を開発しようとしましたが、役に立ちませんでした。そのような提案をいただければ幸いです。