Doing some practice on recursion and map implementation to knock some rust off Clojure. I’m using lists only here so how am I trying to mix seq and non-seqable stuff?
(defn mapset ([operator operand] (mapset operator operand '())) ([operator operand finished-set] (if (empty? operand) '(finished-set) (mapset operator (rest operand) (into finished-set (operator (first operand)))))))
REPL:
namespace.name> (mapset + '(1 3 4 6 5)) Execution error (IllegalArgumentException) at tester.core/mapset (core.clj:38). Don't know how to create ISeq from: java.lang.Long
Advertisement
Answer
Some errors:
- replace
'(finished-set)
withfinished-set
into
adds elements from one collection to another, I think you’re looking forconj
(that’s the source ofIllegalArgumentException
)- and if you’ll use
conj
, you have to use[]
as initialfinished-set
, becauseconj
adds element to beginning of the list, but at the end of the vector
Your function, with minimal changes:
(defn mapset ([operator operand] (mapset operator operand [])) ([operator operand finished-set] (if (empty? operand) finished-set (mapset operator (rest operand) (conj finished-set (operator (first operand)))))))
Tests:
(mapset inc '(1 3 4 6 5)) ; => [2 4 5 7 6] (mapset dec '(1 3 4 6 5)) ; => [0 2 3 5 4]
You can also write it with only two arguments, using cons
:
(defn mapset [operator operand] (if (empty? operand) '() (cons (operator (first operand)) (mapset operator (rest operand)))))
Note that neither version is lazy, that would require adding lazy-seq
.