9

这是我从 clojure 文档站点复制的迷你代码的示例。

(apply map vector (vec jpgList)) 

我猜 map 和 vector 都是函数,但 apply 只需要一个函数。怎么在这里 apply 需要两个函数?

4

4 回答 4

11

阅读以下文档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 不同,Clojuremap支持对多个集合进行操作。(vec jpgList)大概是一个嵌套向量或列表,如下例所示:

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

发生的事情是,由 产生map的每个元素都是嵌套向量元素中每个第 n 个元素的向量。该函数也称为transpose矩阵运算。

于 2013-04-30T14:21:55.083 回答
5

apply接受一个函数及其参数。如果使用两个以上的参数调用,中间的参数将被添加为标量参数(如使用部分参数)。请参阅文档apply

换句话说,所有这四个都是相同的:

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

于 2013-04-30T14:27:02.410 回答
2

只有map被“应用”。然而,第一个参数map本身总是一个函数。在这种情况下vector,被添加到 (vec jpgList) 生成的参数序列中。vector这里不是应用第二个函数,它是序列中的第一个参数,map与其余参数一起应用。

在应用任何本身将函数作为参数的高阶函数时,您会经常看到这个习语。

于 2013-04-30T14:31:07.983 回答
0

考虑一下:

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

'apply' 将 + 应用于通过将 999 附加到 n-coll 形成的参数列表。当相关集合由向量组成时,如果将 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
于 2019-02-09T14:58:41.390 回答