Clojure &引用;应用映射向量";习语-2个函数是如何实现的?

Clojure &引用;应用映射向量";习语-2个函数是如何实现的?,clojure,Clojure,这是我从clojure文档网站复制的迷你代码中的一个示例 (apply map vector (vec jpgList)) 我猜map和vector都是函数,但apply只使用一个函数。为什么在这里应用需要两个功能?阅读apply的文档: user=> (doc apply) ------------------------- clojure.core/apply ([f args] [f x args] [f x y args] [f x y z args] [f a b c d &

这是我从clojure文档网站复制的迷你代码中的一个示例

(apply map vector (vec jpgList)) 

我猜map和vector都是函数,但apply只使用一个函数。为什么在这里应用需要两个功能?

阅读
apply
的文档:

user=> (doc apply)
-------------------------
clojure.core/apply
([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args])
  Applies fn f to the argument list formed by prepending intervening arguments to args.
nil
因此,
(apply map vector(vec jpgList))
对应于
f x args
,因此
map
将应用于函数
vector
,后面是
(vec jpgList)
的元素。与Haskell不同,Clojure的
map
支持对多个集合进行操作
(vec jpgList)
可能是一个嵌套的向量或列表,如以下示例所示:

user=> (apply map vector [[1 2 3] [4 5 6]])
([1 4] [2 5] [3 6])  

实际情况是,
map
生成的每个元素都是嵌套向量元素中每个第n个元素的向量。此函数在矩阵运算中也称为转置。

apply
接受函数及其参数。如果使用两个以上的参数调用,中间的参数将作为标量参数添加(就像使用partial)。看

换句话说,这四项都是相同的:

(apply (partial map vector) [[1 2 3 4] "abcd"])
(apply map [vector [1 2 3 4] "abcd"])
(apply map vector [[1 2 3 4] "abcd"])
(map vector [1 2 3 4] "a b c d")

所有将返回
([1\a][2\b][3\c][4\d])

仅“应用”了
map
。但是,
map
的第一个参数本身始终是一个函数。在本例中,
vector
是由(vec-jpgList)生成的参数序列的前缀
vector
这里不是应用的第二个函数,它是
map
与其余函数一起应用的序列中的第一个参数

当应用任何本身以函数为参数的高阶函数时,您会经常看到这个习惯用法。

考虑一下:

user=> (let [n1 1
  #_=>       n2 2
  #_=>       n-coll [n1 n2]]
  #_=>   (=
  #_=>    (apply + 999 n-coll)
  #_=>    (+ 999 n1 n2)))
true

“apply”将+应用于通过在n-coll前加999而形成的参数列表。当所讨论的集合由向量组成时,如果将map替换为+并将vector替换为999:

user=> (let [r1 [1 2 3]
  #_=>       r2 [4 5 6]
  #_=>       r-coll [r1 r2]]
  #_=>   (=
  #_=>    (apply map vector r-coll)
  #_=>    (map vector r1 r2)))
true