Reputation: 1477
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
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