如何在Clojure中对来自某些结构的多个向量求和

时间:2011-08-12 20:14:24

标签: clojure

SIMPLER版本:

这有效:

user=> (map + [1 2 3] [4 5 6] [7 8 9])
(12 15 18)

这不是:

user=> (for [n (range 3)] [n (+ 1 n)])
([0 1] [1 2] [2 3])
user=> (map + (for [n (range 3)] [n (+ 1 n)]))
java.lang.ClassCastException

为什么?


我对clojure很新,所以这可能是一个新手的错误。在下面的代码中,我试图将多个信号一起添加。每个信号都包含一个矢量(称为数据),我想分段添加。在REPL,这样的事情:

user=> (map + [1 2 3] [4 5 6] [7 8 9])
(12 15 18)

我的代码如下:

(defrecord signal [x y data])
(defrecord sampling [t0 dt n])

(defn random-signal [x y sampling tstart tend]
  (let [t0 (:t0 sampling)
       dt (:dt sampling)
       n (:n sampling)
       random-or-zero (fn [i]
                        (let [t (+ t0 (* dt i))]
                          (if (and (>= t tstart) (< t tend)) (- (* 2 (rand)) 1) 0)))
       data (vec (for [i (range n)] (random-or-zero i)))]
    (signal. x y data)))

(defn add-signals [signals]
  (let [s0 (nth signals 0)]
    (signal. (:x s0) (:y s0) (vec (map + (for [s signals] (:data s)))))))

(let [s (sampling. 0 0.1 10)
     r1 (random-signal 5 6 s 0.3 0.5)
     r2 (random-signal 5 6 s 0 1)]
  (prn r1)
  (prn r2)
  (prn (add-signals [r1 r2])))

随机信号代码工作正常,但代码在带有类强制转换异常的“map +”中失败。所以(无益的)输出是:

#:com.xxx.signal{:x 5, :y 6, :data [0 0 0 0.347104804641861 -0.043159177718418595 0 0 0 0 0]}
#:com.xxx.signal{:x 5, :y 6, :data [0.4956475276522727 -0.5843463943909746 -0.3375682325118188 0.5082971115650308 -0.971067613756232 0.6002887290735672 0.06900015064406251 -0.49986294956362287 0.657705242728329 0.7737992261031372]}
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassCastException (fake.clj:0)
    at clojure.lang.Compiler.eval(Compiler.java:5440)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.Compiler.loadFile(Compiler.java:5820)
    at clojure.main$load_script.invoke(main.clj:221)
    at clojure.main$script_opt.invoke(main.clj:273)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:365)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: java.lang.ClassCastException
    at clojure.lang.LazySeq.sval(LazySeq.java:47)
    at clojure.lang.LazySeq.seq(LazySeq.java:56)
    at clojure.lang.RT.seq(RT.java:450)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:318)
    at com.xxx.fake$add_signals.invoke(fake.clj:60)
    at com.xxx.fake$eval223.invoke(fake.clj:74)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    ... 15 more
Caused by: java.lang.ClassCastException
    at java.lang.Class.cast(Class.java:2990)
    at clojure.core$cast.invoke(core.clj:293)
    at clojure.core$_PLUS_.invoke(core.clj:815)
    at clojure.core$map$fn__3699.invoke(core.clj:2094)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    ... 22 more

Process finished with exit code 1

我做错了什么?

1 个答案:

答案 0 :(得分:2)

这不起作用,

(map + (for [n (range 3)] [n (+ 1 n)]))

因为现在你传递的是seqs的map,seqs(一个seq而不是你的第一个例子中的3个),

这等于,

 (map + [[1 2 3] [4 5 6] [7 8 9]])

如果你这样做,

(apply map + (for [n (range 3)] [n (+ 1 n)]))

它将评估为,

(map + [0 1] [1 2] [2 3])