我正在努力教自己。这只是一个简单的函数,它接受一个值并将每个前面的值相加并返回这些值的总和。
问题是,在loop
函数中,numbers
未使用conj
进行修改,就像我期望的那样 - numbers
只保留一个空向量。那是为什么?
(defn sum
[number]
(do (def numbers (vector))
(loop [iteration number]
(if (> iteration 0)
(conj numbers iteration)
(recur (dec iteration))))
(map + numbers)))
答案 0 :(得分:4)
一些提示(不是答案):
do
。 let
,而不是def
。conj
之前的返回结果,或者它什么都不做。recur
。 此外,您的sum
函数会忽略其number
参数。
我认为您在number
(想要添加的内容的数量)和numbers
(内容本身)之间感到困惑。记住,
first
和rest
代替索引。您要搜索的代码模式非常常见,以至于它已在名为reduce
的标准高阶函数中捕获。你可以得到你想要的效果......
(defn sum [coll] (reduce + coll))
或
(def sum (partial reduce +))
例如,
(sum (range 10))
;45
有些偏离主题:
如果我是你,而我曾经是,我会浏览网上提供的一些精美的clojure教程,使用REPL手持。您可以开始查看here或here。请享用!
答案 1 :(得分:0)
由于以下三个主要原因,您的功能无效:
numbers
的值(但实际上它会返回绑定到另一个名称的副本)loop/recur
模式,就像在经典命令式中一样(它的工作方式不同)map
缩略图给出了惯用的答案,但这里正确使用了您的模式:
(defn sum
[number]
(loop [iteration number
numbers []]
(if (<= iteration 0)
(reduce + numbers)
(recur (dec iteration) (conj numbers iteration)))))
循环/重复模式使用recur
传递的更新值执行其正文。
重新更新loop
后列出的值。这里,虽然迭代严格为正,但执行recur
。但是,当迭代次数达到0时,对多次递归的结果执行(reduce + numbers)
(实际求和),因此递归结束。