2014-04-18 70 views
0

我剛剛完成4clojure Problem 60,這裏的問題描述我的第一個程序代碼:串聯序列

;;Write a function which behaves like reduce, but returns each intermediate 
;;value of the reduction. Your function must accept either two or three arguments, 
;;and the return sequence must be lazy. 
(fn red 
    ([fun sq] 
    (red fun (first sq) (rest sq))) 
    ([fun acum sq] 
    (if (empty? sq) acum 
    (cons acum (lazy-seq (red fun (fun acum (first sq)) (rest sq))))))) 

功能的核心出現一行波紋管的,如果,我只是回到初始值,然後將其應用於序列中的下一個元素。但它沒有第二個測試案例涉及向量:

user=> (red conj [1] [2 3 4]) 
([1] [1 2] [1 2 3] 1 2 3 4);; it should be ([1] [1 2] [1 2 3] [1 2 3 4]) 

我花了一些時間來實現,問題是cons這只是增加了vector[1 2 3 4],因爲它是在列表的其餘部分,而不是作爲一個單一的元素。

我做了什麼是cons轉換爲concatacum[acum]和它的工作:

(fn red 
    ([fun sq] 
    (red fun (first sq) (rest sq))) 
    ([fun acum sq] 
    (if (empty? sq) [acum] 
    (concat [acum] (lazy-seq 
        (red fun (fun acum (first sq)) (rest sq))))))) 

不要問我爲什麼,但在我看來,有種不雅,其他解決方案沒有使用concat都沒有。

現在的問題是,考慮到第一個功能的原因,在不修改代碼的情況下,該功能/宏是如何工作的。

+0

由@Ankur糾正,'(red +())'返回'[nil]'。爲了與'reduce'和'reductions'保持一致,當雙參數調用中'sq'爲空時''red'最好返回'[(fun)]''。 – Thumbnail

回答

3

if真實的案例回報[acum]而不是acum

0

可避免使用CONCAT的,如果你把利弊吧。缺點是懶惰(見利弊與連詞對堆棧溢出的討論):

(defn my-reductions 
    ([f sq] (my-reductions f (first sq) (rest sq))) 
    ([f init sq] 
    (if (empty? sq) 
     (list init) 
     (cons init (lazy-seq (my-reductions f (f init (first sq)) (rest sq)))) 
    ) 
) 
) 

BTW:此代碼將4Clojure測試,但並沒有完全表現得像減少在所有情況下:

(my-reductions + []) 
(nil) 
(reductions + []) 
(0)