Clojure &引用;应用映射向量";习语-2个函数是如何实现的?
这是我从clojure文档网站复制的迷你代码中的一个示例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 &
(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