我發現下面的代碼(在this blog post,解決了Coin Changer Kata):請給我解釋一下下面的Clojure代碼
(defn change-for [amount]
(let [denominations [25 10 5 1]
amounts (reductions #(rem %1 %2) amount denominations)
coins (map #(int (/ %1 %2)) amounts denominations)]
(mapcat #(take %1 (repeat %2)) coins denominations)))
我覺得困難的部分是:(reductions #(rem %1 %2) amount denominations)
。
正如我發現,reductions只是增量計算基於某個給定的所得徵收。例如:(reductions + [1 2 3])
給出[1 3 6]
。
1 ; first element
1 + 2 ; second element
1 + 2 + 3 ; third element
下一個計算餘數的函數rem仍然非常容易理解。
理解代碼的其餘部分我試過如下:
; first try, to see if this call works
; outside the original code (the change-for function)
(reductions #(rem %1 %2) 17 [10 5 1]) ; --> [17 7 2 0]
; tried to use the reductions which takes only one argument
; notice that 17 is now inside the array
(reductions #(rem %1 %2) [17 10 5 1]) ; --> [17 7 2 0]
; further simplified the expression
(reductions rem [17 10 5 1]) ; --> [17 7 2 0]
的最後一步是在this blog post描述刪除匿名函數。
在這裏,事情變得混亂(至少對我來說):rem
需要2個參數,我不明白它如何使用數組[17 10 5 1]
時如何應用它們。我嘗試了以下電話:
(rem [17 10 5 1]) ; --> gives error
(rem [17 10 5 1] [17 10 5 1]) ; --> also gives error
(rem 17 10) ; --> works, but how do you use it with collections?
有人能解釋我,這rem
功能與reductions
功能是如何工作的?
我不太明白的另一件事是:這些百分比參數是如何應用的(在#(rem %1 %2)
)?我的意思是他們來自哪裏?我嘗試通過以下方式撥打rem
,但出現錯誤:(#(rem %1 %2) 17 [10 5 1])
。必須有一些reductions
函數在幕後進行這項工作,對吧?
起初我以爲#(rem %1 %2)
是一套。這些都是以類似的方式爲集合聲明的,很容易被濫用(有人剛開始使用Clojure):
(type #{1 2 3}) ; --> clojure.lang.PersistentHashSet
(type #(1 2 3)) ; --> user$eval12687$fn__12688
有人點我到一個網站/書籍/任何解釋Clojure的技巧如「匿名函數的特殊形式」?大多數資源只是給出了最簡單的構造(與所有其他lisp派生類似的構造),而沒有涉及Clojure的複雜性。我發現a site看起來不錯(也解釋了我上面提到的匿名函數)。 任何其他此類資源?