关于clojure:无法将LazySeq强制转换为Number

LazySeq cannot be cast to Number

我正在尝试实现一个返回伯努利数字的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(defn binom [N K]
    (if (or (= K 0) (= N K))
        (int 1)
        (int (+ (binom (- N 1) (- K 1))
                (binom (- N 1) K)))))

(defn bernoulli [M]
    (if (= M 0)
        (int 1)
        (for [K (range 0 (- M 1))]
            (* (binom M K)
               (bernoulli K)))))

(println (bernoulli 5))

(显然,它尚未正确实现,但这与我的问题无关)

运行该程序时,出现异常java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number

但是,如果将递归调用(bernoulli K)替换为(bernoulli 0),则代码可以正常运行。

这里发生了什么? 为什么我的binom函数可以将K当作数字处理,但是我的bernoulli函数却不能呢?

这是完整的错误消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ clojure bern.clj
(Exception in thread"main" java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number
    at clojure.lang.Numbers.multiply(Numbers.java:146)
    at user$bernoulli$iter__3__7$fn__8$fn__9.invoke(x2.clj:21)
    at user$bernoulli$iter__3__7$fn__8.invoke(x2.clj:18)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:473)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$print_sequential.invoke(core_print.clj:46)
    at clojure.core$fn__5270.invoke(core_print.clj:140)
    at clojure.lang.MultiFn.invoke(MultiFn.java:167)
    at clojure.core$pr_on.invoke(core.clj:3266)
    at clojure.core$pr.invoke(core.clj:3278)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.core$apply.invoke(core.clj:601)
    at clojure.core$prn.doInvoke(core.clj:3311)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:601)
    at clojure.core$println.doInvoke(core.clj:3331)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at user$eval18.invoke(x2.clj:29)
    at clojure.lang.Compiler.eval(Compiler.java:6514)
    at clojure.lang.Compiler.load(Compiler.java:6955)
    at clojure.lang.Compiler.loadFile(Compiler.java:6915)
    at clojure.main$load_script.invoke(main.clj:283)
    at clojure.main$script_opt.invoke(main.clj:343)
    at clojure.main$main.doInvoke(main.clj:427)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:415)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)

bernoulli中的第二个条件是对for的调用,该调用返回一个lazy-seq,但是您试图对其进行算术运算,这是完全无效的。 也许您想用(apply + (for ...))求和,该结果使用for返回的值作为+的args(我不知道具体算法在我头上,也许您想要一个平均值或 产品而不是总和...)。