首先,我們不談論方法的簡寫:我們談論的功能。 clojure中有些東西可以調用方法,但它與函數不同。如果你停止使用OO術語,你也將失去OO風格。
你正在嘗試做什麼是可能的。您基本上想要在dupseqx
函數中創建名稱爲dupx
的新函數。你現在正在做的是創建一個函數,然後把它扔掉(你不用做返回值,只返回函數中的最後一個表單)。由於函數與任何其他值一樣,因此可以像使用其他任何值一樣使用相同的機制:創建本地「變量」。這是什麼機制?這是本地綁定和它的工作原理是這樣的(在FN的名稱只是讓你可以從自身調用它,它並不需要是相同let
結合的名稱):
(let [dupx (fn dupx [v x]
(if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
公告我糾正了其他一些事情。
這方面的一個較短的形式(固定雙名醜):
(letfn [(dupx [v x] (if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
好兩者之間「的一切(讓[...]」和匹配的‘)’我們現在有一個dupx
功能
所以,現在你的代碼的其餘部分作品:
(fn dupSeqX [aseq x]
(letfn [(dupx [v x] (if (= x 1) (list v) (cons v (dupx v (dec x)))))]
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq))))
該代碼可以由多一點地道:
- 編碼指南:名稱參數的
coll
代替aseq
- 編碼指南:DoNotUseCamalCase做它喜歡 - 這
- 遞歸當你不需要它時,對性能和大數據都是不利的。
- 你正在重新發明車輪。這對學習編碼很有幫助,但如果你想了解語言和標準庫,那就不好了。
我怎麼去寫呢?
首先是基本的fn。 coll
是預期序列命名函數的標準。
(fn [coll times] )
如果你讀到這個「序列的每個元素」,你的大腦必須去MAP。
(fn [coll times]
(map (fn ....) coll))
「複製每個...」基本上是你必須放入map函數的描述。我們可以使用repeat
(你的配音功能,但有一些額外的好東西,比如懶惰)。
(fn [coll times]
(map (fn [val] (repeat times val)) coll))
還有一個問題(來自koan)。它希望返回一個seq,而不是每個元素的序列中的一個序列。這意味着我們必須將結果連接在一起。
(fn [coll times]
(apply concat (map (fn [val] (repeat times val)) coll)))
您會經常看到(apply concat (map ....))
模式。標準庫中有一個更好的函數,名爲mapcat
,我將把內部函數變成簡短的語法。
(fn [coll times]
(mapcat #(repeat times %) coll))
希望有幫助!
這裏有一些提示。我認爲你的意思是功能而不是方法。另外,函數是用defn定義的,但匿名函數(lamdba)是用fn定義的。你混淆了兩者。另外,如果您需要在外部函數範圍內使用本地函數,請使用let或letfn。 –