我正在尋找一個Clojure函數,我們稱之爲anyargs
,它允許函數參數忽略多餘的參數。因此,例如,是否有一個適配器使函數能夠忽略多餘的參數?
((anyargs cons) :a [:b :c] :d) ; => (:a :b :c)
如果函數的參數了幾arities,這將是一件好事,如果最大擬合一個選擇。
我正在尋找一個Clojure函數,我們稱之爲anyargs
,它允許函數參數忽略多餘的參數。因此,例如,是否有一個適配器使函數能夠忽略多餘的參數?
((anyargs cons) :a [:b :c] :d) ; => (:a :b :c)
如果函數的參數了幾arities,這將是一件好事,如果最大擬合一個選擇。
一種方法是檢查函數,看看它需要多少個參數。 This link涵蓋了檢測這一點的方法。
如果修改答案咯,你得到的參數的最大數量:
(defn n-args [f]
(-> f class .getDeclaredMethods last .getParameterTypes alength))
這隻能如果方法陣列由參數的長度,這在我的系統似乎是這樣的組織。如果你真的想確保,
(defn n-args [f]
(apply max
(map #(-> % .getParameterTypes alength)
(-> f class .getDeclaredMethods))))
然後,你可以寫:
(defn anyargs [f]
(let [n (n-args f)]
(fn [& args] (apply f (take n args)))))
本使用反射,它打破了與可變參數的功能,但想必你不會用可變參數的函數使用它。這是目前我能想到的最好的方法,除了提供一個封裝來捕獲ArityException,並且一直使用更少和更少的參數進行重試,直到它工作。
我認爲你必須破解它。
(defn max-arities [f]
(reduce
#(merge-with max % {(.getName %2) (alength (.getParameterTypes %2))})
{}
(seq (.getDeclaredMethods (class +)))))
(defn anyargs [f]
(let [accept (if (instance? clojure.lang.RestFn f)
identity
(partial take ((max-arities f) "invoke")))]
(fn [& args] (apply f (accept args)))))
((anyargs cons) :a [:b :c] :d) ;=> (:a :b :c)
((anyargs +) 1 2 3 4 5 6 7 8 9 10) ;=> 55
不乾淨,因爲Clojure沒有通過公開的API公開其函數的arity。
既然你要知道,你要應用的功能的元數,這是很容易在特定情況下,其中n是元數
#(apply f (take n %&))
實現這一目標