对iterate
的大多数引用都是针对运算符的,并且函数上的所有应用程序都非常混乱,我仍然无法在代码中使用iterate
以及partial
是
我正在做一个编程作业,试图用牛顿的方法得到一个数字n的平方根。也就是说,将猜测作为初始近似值,通过计算近似值和n /近似值的平均值来保持计算新的近似值。继续,直到两个最近的近似值之间的差异小于epsilon。
我首先尝试做近似部分,我相信这是我需要使用迭代和部分。后来,epsilon是我需要使用“take”的东西吗?
这是我没有epsilon的近似代码:
(defn sqrt [n guess]
(iterate (partial sqrt n) (/ (+ n (/ n guess)) 2)))
但是,当我输入(sqrt 2 2)
时,此代码无法正常运行,它会给我(3/2 user=> ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure.lang.Numbers.divide (Numbers.java:155)
。
我想这是我需要反复迭代的部分?有人可以给我一些提示吗?再次,这是一个家庭作业问题,所以请不要直接解决整个问题,我需要一些我可以学习的想法和解释。
答案 0 :(得分:4)
partial
为该函数接受一个函数和至少一个参数,并返回一个需要其余参数的新函数。
(def take-five (partial take 5))
(take-five [1 2 3 4 5 6 7 8 9 10])
;=> (1 2 3 4 5)
iterate
通过采用两个参数生成无限序列:函数和种子值。种子值用作生成列表中的第一个元素,第二个元素通过将函数应用于种子来计算,第二个值用作函数的输入以获取第三个值,依此类推。
(take-five (iterate inc 0))
;=> (0 1 2 3 4)
ClojureDocs提供了有关这两个功能的良好文档:http://clojuredocs.org/clojure_core/clojure.core/iterate和http://clojuredocs.org/clojure_core/clojure.core/partial。
答案 1 :(得分:3)
所以,@ apzao很好地解释了iterate
和partial
做了什么,而@yonki指出你并不真正需要它。如果你想探索一些更多的seq函数,那么无论如何都要尝试它是个好主意(尽管延迟序列的开销可能会导致一些不太理想的性能)。
提示:
(iterate #(sqrt n %) initial-approximation)
将为您提供一系列近似值。 partition
创建后续近似对。 drop-while
使用序列来解决这个问题可能是非常有益的,因为你接触了许多有用的seq函数。
注意:此答案的编辑历史记录中有完整的解决方案。对不起,没有完全得到“功课”部分。
答案 2 :(得分:0)
我认为你错过了这一点。您也不需要iterate
partial
。
如果需要执行某些计算直到满足条件,则可以使用易于理解的loop/recur
指令。 loop/recur
可以理解为:做一些计算,检查是否满足条件,如果是,则返回计算值,如果不重复计算。
既然你不想要整个解决方案,只需要建议去哪里,在loop/recur
上看一看,一切都会好的。
@noisesmith说得好。 reduce
不是用于计算直到条件完全填充,但在使用有限步数执行某些计算时可能很有用。