2017-06-03 21 views
1

我有下面的函數定義地圖編輯爲什麼Clojure的給這個參數數量錯誤

(def map-edit 
    (fn [m lst k f] 
    (if (car lst) 
     (assoc m 
      (car lst) 
      (map-edit (get m (car lst) {}) k f)) 
     (assoc m k (f (get m k)))))) 

當我嘗試調用這個函數在我REPL

(map-edit {} (list "oeu") "oeuoeu" (fn [q] "oeu")) 

我得到的元數錯誤

ArityException Wrong number of args (3) passed to: core/map-edit clojure.lang.AFn.throwArity (AFn.java:429) 

爲什麼它認爲我只傳遞3個參數?

; CIDER 0.8.2 (Java 1.8.0_121, Clojure 1.8.0, nREPL 0.2.12) 
+0

正如一個側面說明 - 它看起來像你正試圖重新實現'clojure.core'的功能'更新in' - 它可能對你會有所幫助看[在它的源代碼](https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/clj/clojure/core.clj#L6054)作爲這種類型的例子遞歸通常在Clojure中完成。 –

+0

@AlephAleph你是完全正確的。感謝您的鏈接和評論(使用update-in應該是被接受的答案) – SultanLegend

回答

6

假設你有這些定義

(def car first) 
(def cdr rest) 

映射編輯只使用3個參數行的遞歸調用可能應該是

(map-edit (get m (car lst) {}) (cdr lst) k f)) 

確保你看堆下一次更仔細追蹤錯誤。

+0

@amalloy我使用三重反引號(''')來表示代碼之前。什麼是最好的方式來做到這一點? – SultanLegend

+0

您可以查看我所做的編輯:全行代碼片段應縮進四個空格。 Stack Overflow的編輯器也有一個按鈕,可以爲你做到這一點。 – amalloy

0

注意

假設@SultanLegend's answer是正確的(不接受,因爲我寫的),核心update-in做了你所需要的。你可以定義...

(defn map-edit [m lst k f] 
    (update-in m (conj (vec lst) k) f)) 

(map-edit {} (list "oeu") "oeuoeu" (fn [q] "oeu")) 
=> {"oeu" {"oeuoeu" "oeu"}} 
相關問題