Is there an adapter that allows a function to ignore extra arguments?

I am looking for a Clojure function, I will call it anyargs, which allows the function argument to ignore the extra arguments. For example,

((anyargs cons) :a [:b :c] :d) ; => (:a :b :c)

If the function argument took several artifacts, it would be nice if the largest suitable one were chosen.

+4
source share
3 answers

One approach is to examine the function to find out how many arguments it takes. This link describes how to detect just that.

If you change this answer a bit, you will get the maximum number of arguments:

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

, , , , . , , , ArityExceptions , .

+4

, .

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

, , , , n - arity

#(apply f (take n %&))
+1

Source: https://habr.com/ru/post/1534463/


All Articles