Clojure示例:我无法理解"%2"的价值是什么?和"%1" in"(str%2%1)"

时间:2014-12-06 22:10:46

标签: clojure functional-programming lisp

我正在做一些关于clojure(初学者)的研究,我发现了一个例子,事情是我无法理解“(str%2%1)”中“%2”和“%1”的值是什么。完整示例如下:

(defn my-reverse [s]
  (let [lst (list)]
    (reduce #(str %2 %1)
             (mapcat #(conj lst %1) s))))  

我理解%2引用了第二个参数,但我只在“#(str%2%1)”之后看到一个参数值,它是mapcat表达式,应该是%1。

感谢您的帮助。希望我已经清楚了。

2 个答案:

答案 0 :(得分:3)

#(str %2 %1)reduce的第一个参数:

  

(减少f coll)

     

f应该是2个参数的函数...返回应用的结果   f到coll中的前2项,然后将f应用于该结果和   第3项等等。

因此f的一个参数是要处理的当前值(集合coll中的当前项),另一个是到目前为止的累积结果。

在这种情况下,(mapcat #(conj lst %1) s)的结果是集合。在第一次调用#(str %2 %1)时,参数%1%2将是该集合中的前两个值。下次将使用该结果和集合中的第三个值调用它。因此,构建一个包含(mapcat #(conj lst %1) s)生成的所有值的字符串。

答案 1 :(得分:3)

符号#(...)是创建匿名函数的简写。

创建匿名函数的更长方法是lambda表达式,由clojure中的符号fn引入:

(fn [arg1 arg2]
  (do-something-with arg1 arg2))

简写允许您省略fn和参数列表,而不是使用默认参数名称:

#(do-something-with %1 %2)

所以,你的例子扩展了:

#(str %2 %1)

扩展为

(fn [thing1 thing2]
  (str thing2 thing1))

#(conj lst %1)

扩展为

(fn [thing]
  (conj lst thing))