Попрактикуюсь в рекурсии и реализации карт, чтобы избавиться от ржавчины на Clojure. Я использую списки только здесь, так как я пытаюсь смешивать последовательные и неразделяемые вещи?
(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)))))))
РЕПЛ:
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
Эта ошибка означает, что вы случайно даете целое число, когда оно ожидает последовательность (список, вектор и т. д.):
demo.core=> (first 5)
Execution error (IllegalArgumentException) at demo.core/eval2055 (form-init5218243389029929734.clj:1).
Don't know how to create ISeq from: java.lang.Long
Некоторые ошибки:
'(finished-set)
на finished-set
into
добавляет элементы из одной коллекции в другую, я думаю, вы ищете conj
(это источник IllegalArgumentException
)conj
, вы должны использовать []
в качестве начального finished-set
, потому что conj
добавляет элемент в начало списка, но в конец вектораВаша функция с минимальными изменениями:
(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)))))))
Тесты:
(mapset inc '(1 3 4 6 5))
; => [2 4 5 7 6]
(mapset dec '(1 3 4 6 5))
; => [0 2 3 5 4]
Вы также можете записать его только с двумя аргументами, используя cons
:
(defn mapset [operator operand]
(if (empty? operand)
'()
(cons (operator (first operand))
(mapset operator (rest operand)))))
Обратите внимание, что ни одна из версий не является ленивой, для этого потребуется добавить lazy-seq
.
Браво! Это сработало. Интересно, что, пытаясь исправить ошибки, я добрался до кода, который вы вставили (на самом деле я дважды проверил, регрессировав код на несколько шагов назад, и да, вот оно). ЕДИНСТВЕННАЯ разница была в том, что возврат после пустого? проверка была в скобках. Это привело меня к «Ошибке выполнения (ArityException) в tester.core/mapset (core.clj: 37). Неверное количество аргументов (0) передано в: clojure.lang.PersistentVector Знаете ли вы, что вызвало это?
Вы выразились более красноречиво, чем я мог бы. Я подозревал, что это одна из возможных причин, но точно не знал. В будущем я буду иметь это в виду.