来自Functional Java和一点Scala,我现在正逐步学习Clojure。 目前,考虑到我有空闲时间,我正在阅读和练习计算机程序的结构和解释"
我坚持以下练习,我知道如何解决问题,即完全删除let
并将(take 2 ...
直接放入map
。
; Exercise 1.3
;; Define a procedure that takes three numbers as arguments
;; and returns the sum of the squares of the two larger numbers.
(defn square-sum-largest-pair [a b c]
"Sums the square of the largest two number of the three in input.
Maybe a little overkill to use a list here, but it's just for fun."
(let [[two-items] (take 2 (reverse (sort [a b c])))]
(reduce + (map (fn [x] (m/expt x 2)) two-items))))
执行square-sum-largest-pair
时会显示以下错误:
actual: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
at clojure.lang.RT.seqFrom (RT.java:505)
clojure.lang.RT.seq (RT.java:486)
clojure.core$seq.invoke (core.clj:133)
clojure.core$map$fn__4245.invoke (core.clj:2551)
为什么会这样?
答案 0 :(得分:3)
问题是[]
轮two-items
。这会将two-items
绑定到序列(take 2 (reverse (sort [a b c])))
的第一个,忽略其余部分。试图使用这个 - 最大数字 - 作为后续map
中的序列产生观察到的错误。
删除[]
(为了简单起见与*
平方),我们得到了
(defn square-sum-largest-pair [a b c]
(let [two-items (take 2 (reverse (sort [a b c])))]
(reduce + (map (fn [x] (* x x)) two-items))))
(square-sum-largest-pair 1 2 3)
13
答案 1 :(得分:3)
因为你总是处理来自seq前面的相同固定数量的项目,你也可以通过使用解构为第一个元素创建绑定来解决这个问题:
(defn square-sum-largest-pair [a b c]
(let [[x y] (reverse (sort [a b c]))]
(+ (* x x) (* y y))))
答案 2 :(得分:1)
不要将括号括起来两次。作为奖励,我对其进行了修改,因此您无需撤消已排序的列表:
(defn square-sum-largest-pair [a b c]
"Sums the square of the largest two number of the three in input.
Maybe a little overkill to use a list here, but it's just for fun."
(let [two-items (take 2 (sort > [a b c]))]
(reduce + (map (fn [x] (m/expt x 2)) two-items))))