将变量列表单独传递给clojure函数

wes*_*erA 4 clojure currying destructuring

我一直在玩clojure,并决定创建一个更高阶的函数,它结合了mapcat和list来模拟这种行为:

Clojure> (mapcat list '(1 2 3 4) '(5 6 7 8))
(1 5 2 6 3 7 4 8)
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试是定义mapcatList,如下所示:

Clojure> (defn mapcatList[& more](mapcat list more))
#'sandbox99/mapcatList
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8))
((1 2 3 4) (5 6 7 8))
Run Code Online (Sandbox Code Playgroud)

显然这个函数并不像我想要的那样,我认为这是因为这两个列表被放入一个列表并作为单个参数传递,而不是两个.我能够通过以下方式纠正这种情况,

Clojure> (defn mapcatList[x y & more](mapcat list x y))
#'sandbox99/mapcatList
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8))
(1 5 2 6 3 7 4 8)
Run Code Online (Sandbox Code Playgroud)

这个解决方案适用于两个列表,但我希望该函数使用可变数量的参数.

我的问题:如何将一个可变数量的参数传递给一个函数,然后对它们进行解构,使它们作为单独的参数一起传递给'mapcat list'?

Chr*_*erg 14

你在找apply.这将使用序列中提供的参数调用函数.

但是你知道有一个功能interleave完全符合你的mapcatList尝试吗?


sku*_*uro 5

你是对的,由于vararg声明,参数被包装在一个列表中.您需要apply参数才能解包参数列表:

(defn mapcatList[& more]
  (apply mapcat list more))

user=> (mapcatList '(1 2 3 4) '(5 6 7 8))               
(1 5 2 6 3 7 4 8)
user=> (mapcatList '(1 2 3 4) '(5 6 7 8) '(\a \b \c \d))
(1 5 \a 2 6 \b 3 7 \c 4 8 \d)
Run Code Online (Sandbox Code Playgroud)