让绑定序列作为输入映射,抛出异常

时间:2014-08-02 15:28:15

标签: clojure sicp

来自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)

为什么会这样?

3 个答案:

答案 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))))