clojure рекурсия создает список

((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5)

Для этого кода результатом будет [5 4 3 2 1]. Почему это не [1,2,3,4,5]? Я вижу, что мы делаем conf из результата рекурсивного вызова foo со значением. Ибо я думал, что должно быть 1 2 3 4 5? Нужна помощь, чтобы понять это. Спасибо.


person BufBills    schedule 03.08.2015    source источник


Ответы (2)


Из документации conj:

clojure.core/conj
([coll x] [coll x & xs])
conj[oin]. Возвращает новую коллекцию с добавленным xs
. (conj nil item) возвращает (item). "Добавление" может
происходить в разных "местах" в зависимости от конкретного типа.

Условие завершения вашей функции дает nil, потому что тест - это когда. Таким образом, самый глубокий вызов conj будет:

(conj nil 1)
(1) <-- a list

Следующий:

(conj (conj nil 1) 2)
(2 1)

Таким образом, ваш результат будет в порядке убывания, потому что conj добавляется впереди для списков. Если вы хотите, чтобы это было в порядке возрастания, начните с пустого вектора, например:

((fn foo [x] (if (> x 0) (conj (foo (dec x)) x) [])) 5)
[1 2 3 4 5]
person Diego Basch    schedule 03.08.2015

Рекурсивный вызов расширяется до

(conj (conj (conj (conj (conj nil 1) 2) 3) 4) 5)
;(5 4 3 2 1)

Неявный nil, возвращаемый (foo 0), каламбурит ().

person Thumbnail    schedule 03.08.2015