2014-04-01 31 views

回答

4

一種方法是檢查函數,看看它需要多少個參數。 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,並且一直使用更少和更少的參數進行重試,直到它工作。

1

我認爲你必須破解它。

(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 
1

不乾淨,因爲Clojure沒有通過公開的API公開其函數的arity。

既然你要知道,你要應用的功能的元數,這是很容易在特定情況下,其中n是元數

#(apply f (take n %&)) 
實現這一目標
相關問題