Несоответствие с последовательностями Clojure? - PullRequest
10 голосов
/ 16 сентября 2011

Clojure:

1:13 user=> (first (conj '(1 2 3) 4))
4
1:14 user=> (first (conj [1 2 3] 4))
1
; . . .
1:17 user=> (first (conj (seq [1 2 3]) 4))
4

Я понимаю, что происходит, но должно ли это работать по-другому?

Ответы [ 2 ]

20 голосов
/ 16 сентября 2011

Документация для conj (от clojure.org ):

Призывание [ойн]. Возвращает новую коллекцию с хз «Добавил». (продолжение) возвращает (элемент). «Дополнение» может происходят в разных «местах» в зависимости от типа бетона.

Более эффективно «добавлять» элементы в конец вектора, в то время как более эффективно это делать в начале списков. conj использует все, что наиболее эффективно для структуры данных, которую вы ей предоставляете.

В приведенных вами примерах '(1 2 3) и (seq [1 2 3]) оба реализуют ISeq (см. Документацию для seq?), а [1 2 3] - нет.

Clojure conj в конечном счете вызывает метод cons (не путать с функцией cons - этот метод является внутренним кодом clojure) для базовой структуры данных; для векторов (PersistentVector) cons добавляет элементы в конец, тогда как для списков они добавляются вперед (метод cons для PersistentList s возвращает новый список с новым элементом в качестве заголовка, и существующий список как его хвост).

6 голосов
/ 16 сентября 2011

Если вы посмотрите на Структуры данных Clojure

вы увидите, что коннект работает по-разному со списками и векторами.

con помещает добавленный элемент в начало списка и в конец вектора.

Я также предлагаю посмотреть Clojure API.

, который имеет несколько хороших примеров. В целом, у ClojureDocs есть несколько очень хороших примеров для большинства команд Clojure.

...