clojure减少。没有起始值,空集合

时间:2015-12-11 09:30:57

标签: clojure functional-programming

谜语中,我必须完成以下表达式才能评估为true。必须有一个插入,适合所有这些。

(= 15 (reduce __ [1 2 3 4 5]))
(=  0 (reduce __ []))
(=  6 (reduce __ 1 [2 3]))

第三个表达式提供起始值。因此,我的替代品不能提供另一个。

这个函数将通过第一个和第三个真值测试:

#(+ %1 %2)

但是,第二个表达式会产生以下错误:

clojure.lang.ArityException:错误的args(0)传递给(...我的函数id)

看起来通常只有当起始值+集合的长度大于2时才调用给定函数。如果此长度为0,就像上面的情况一样,它也被调用 - 带有0个参数。

有没有人提示如何继续进行?

1 个答案:

答案 0 :(得分:0)

从评论来看,解决方案显然是+,但是看一下为什么可能会有一些细节。事实证明,它有很多。

首先,让我们看看reduce,了解要求是什么:

(defn reduce
  "f should be a function of 2 arguments. If val is not supplied,
  returns the result of applying f to the first 2 items in coll, then
  applying f to that result and the 3rd item, etc. If coll contains no
  items, f must accept no arguments as well, and reduce returns the
  result of calling f with no arguments.  ..."
  ... 
  ([f coll]
     (if (instance? clojure.lang.IReduce coll)
       (.reduce ... coll f)
       ...))
  ([f val coll]
     (if (instance? clojure.lang.IReduceInit coll)
       (.reduce ... coll f val)
       ...)))

这是一个多功能函数,可以使用函数和集合,也可以是函数,初始值和集合。

+也是一个多元函数,其行为取决于传递给它的参数数量。下面的源代码(针对我们关心的部分进行了编辑)显示了0-arity和2-arity满足reduce。

(defn +
  "Returns the sum of nums. (+) returns 0..."
  ...
  ([] 0)
  ...
  ([x y] (. clojure.lang.Numbers (add x y)))
  ...

显然(reduce + [])调用第一个子句并返回0.解释了测试2。

这适用于第一次测试,方法是在紧密的for循环中将add函数应用于每对数字which happens in the Java internals for Clojure

最终测试与第一个测试完全相同,只是它调用了[v val coll] reduce的实现。这适用a slightly different internal function,但效果相同。

备注

[1]:IFnJava interface for clojure functions