Joel
Joel

Reputation: 1477

Why am I getting a LazySeq casting error?

I've written the following function

(defn insert-block
  "Given a block, coordinate and playfield, returns the altered playfield.
   Does not check for collisions."
  [[x y] block playfield]
  (let [blocksize (count block)
    insertion (fn [a b] (vector (block a) (playfield b)))
    block-indicies (range 0 blocksize)
    field-indicies (range y (+ y blocksize))]
    (map insertion block-indicies field-indicies))) 

Block and playfield are both vectors of vectors. For some reason, every time I call this function, I get the following error:

#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn>

The function has been simplified a bit from what's in my code - 'insertion' is more complex in the original, but I get the same error regardless. This is driving me nuts - Does anyone have any ideas?

EDIT: I've been testing it with [2 3] for [x y] and [[0 0 0] [0 1 0] [1 1 1]] for block. Playfield is too large to paste here, but it's a vector of 26 vectors containing integers, of length 14.

EDIT2: Here's the playfield vector.

[[1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1]]

EDIT3: I've narrowed it down further - the following code works. It seems that accessing elements in the block and playfield vectors is what's causing the problem, but I still don't know why.

(defn insert-block
"Given a block, coordinate and playfield, returns the altered playfield.
 Does not check for collisions."
[[x y] block playfield]
(let [blocksize (count block)
  insertion (fn [a b] (vector a b))
  block-indicies (range 0 blocksize)
  field-indicies (range y (+ y blocksize))]
  (map insertion block-indicies field-indicies))) 

Thanks

Upvotes: 2

Views: 5247

Answers (1)

Daan
Daan

Reputation: 1546

I'm pretty sure you're not really passing vectors to your function. It works for the vectors you supplied, using clojure 1.3.

A safer way to retrieve the nth value from a collection in clojure is the nth function. This function will work for whatever type of collection you pass in, lists, vectors, sequences and more.

As Joost commented, your function returns a lazy sequence, which might not be what you want. If you absolutely need a vector back you could pass the result of map to vec.

Upvotes: 7

Related Questions