Clojure ClassCastException长到IFn

时间:2014-02-13 14:07:13

标签: clojure

我是clojure的新手,我正在尝试制作一个用复数做数学的小程序。我尝试了多个版本的乘法函数,它们都给出了相同的错误。对于其他一些功能,使用let修复它但不在这里。 im-make只返回一个包含实数和虚数的向量。

(defn im-mult
  ([i j]
    (let [a (first i)
          b (second i)
          x (first j)
          y (second j)]
  (im-make (- (* (a) (b)) (* (x) (y)))
             (+ (* (a) (b)) (* (x) (y)))))))

给出两个具有实数和虚数的向量,=> (im-mult x y)

ClassCastException java.lang.Long无法强制转换为clojure.lang.IFn ComplexMath.core / im-mult(NO_SOURCE_FILE:7)

我只想说,哇!没想到clojure在这里有这么多的支持,感谢你的建议,错误当然是括号和不正确的乘法。

2 个答案:

答案 0 :(得分:2)

1)你需要摆脱a,b,x和y周围的额外parens。

2)任何时候你看到一堆第一和第二,这是一个很好的线索,你应该解构你的输入:

(defn im-mult
  [i j]
  (let [[a b] i
        [x y] j]
    (im-make (- (* a b) (* x y))
             (+ (* a b) (* x y)))))

我会一直推荐#1。这可能是一个停止可读性的好地方,但对于笑容,我们可以继续推动它......

3)我观察到(* a b)和(* x y)被使用了两次,所以根本不需要进行结构化 - 我们可以将*应用于i和j:

(defn im-mult
  [i j]
  (let [ab (apply * i)
        xy (apply * j)]
    (im-make (- ab xy)
             (+ ab xy))))

4)我观察到你对两个输入都应用了相同的操作,所以不妨在输入中映射操作。

(defn im-mult
  [i j]
  (let [m (map #(apply * %) [i j])]
    (im-make (apply - m)
             (apply + m))))

5)相同观察 - 和+ ...

(defn im-mult
  [i j]
  (let [m (map #(apply * %) [i j])
        s (map #(apply % m) [- +])]
    (apply im-make s)))

此时,很难看到代码的意图。但是,我认为一个原因是你已经将输入数量固定为2.我怀疑这里有一个n维算法,并采用[& i]作为输入将引导您到一个更美丽的地方,同时也改善代码。

答案 1 :(得分:0)

不需要围绕abxy的额外括号。此外,他们让Clojure尝试将数字解释为函数。这应该解决它:

(defn im-mult
  ([i j]
    (let [a (first i)
          b (second i)
          x (first j)
          y (second j)]
      (im-make (- (* a b) (* x y))
           (+ (* a b) (* x y))))))