Reputation: 991
I'm trying to implement a function that returns Bernoulli numbers:
(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))
(Obviously it's not correctly implemented yet, but that is irrelevant to my question)
When I run this program, I get the exception java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number
.
However, if I replace the recursive call (bernoulli K)
with (bernoulli 0)
, the code runs fine.
What is going on here? Why can my binom function handle K as a number alright, but my bernoulli function can't?
Here's the entire error message:
$ 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)
Upvotes: 3
Views: 1702
Reputation: 20194
The second condition in bernoulli
is a call to for
, which returns a lazy-seq, but you are trying to invoke an arithmetic operation to it, which is simply invalid. Perhaps you want to sum the result with (apply + (for ...))
, which uses the values returned by for
as args to +
(I don't know the specific algorithm off the top of my head, maybe you want an average or a product rather than a sum...).
Upvotes: 4