我是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在这里有这么多的支持,感谢你的建议,错误当然是括号和不正确的乘法。
答案 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)
不需要围绕a
,b
,x
和y
的额外括号。此外,他们让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))))))