2013-10-06 6 views
7

В чем разница между использованием cons для объединения элемента в список и использованием cons для объединения списка в элемент в схеме?Элемент cons для списка vs cons для элемента в схеме

Кроме того, как именно действуют минусы? Добавляет ли элемент в конец списка или начало?

Спасибо!

+2

@ Ответ ÓscarLοpez expla это очень хорошо. Полезно понять, что в семействе языков Lisp не совсем правильно думать о 'cons' как о операции _list_. Языки Lisp обычно имеют _cons cells_ как подлинные типы данных, а затем реализуют списки как массивные типы данных. То, что мы называем списками, - это списки _by convention_. Я упомянул об этом в [более раннем ответе] (http://stackoverflow.com/a/19126410/1281433), в котором описывается, как мы можем часто скрывать ячейки в списках _implement_, но как мы можем также препятствовать ячейкам для реализации других структур, таких как деревья. –

+0

@JoshuaTaylor Страница Не найдено. –

+0

@hanQiu Я думаю, что вопрос был удален. Но теперь есть раздел в документации SO, который охватывает ту же идею: [списки как соглашение] (http://stackoverflow.com/documentation/common-lisp/2622/cons-cells-and-lists/8700/lists-as -a-конвенция # т = +201608091045099806348) –

ответ

20

Примитив cons просто связывает две вещи, факт, что некоторые из этих вещей считаются списками случайным. Например, это работает и создает пару (также известную как клетка конса):

(cons 1 2) 
=> '(1 . 2)  ; a pair 

Теперь, если второй аргумент cons случается список, то результат будет новым список, и первый аргумент cons будет добавлен во главе старого списка. Другими словами: создать список вам нужен список, даже если он пуст:

(cons 1 '(2 3)) 
=> '(1 2 3)  ; a list 

(cons 1 (cons 2 '())) 
=> '(1 2)  ; a list 

(cons 1 '()) 
=> '(1)   ; a list 

Но если второй аргумент cons является не список, то результат будет просто пара, или неподходящий список, что означает, что она не заканчивается в '(), как это следует рассматривать список:

(cons '(1 2) 3) 
=> '((1 2) . 3) ; a pair, not a list 

(cons 1 (cons 2 3)) 
=> '(1 2 . 3) ; an improper list 

Просто чтобы прояснить, вы не можете использовать cons для добавления элементов в конец списка. Обычный способ построения списка происходит справа налево, добавление элементов в обратном направлении в положении головы - говорят, что вы хотите построить список '(1 2 3), то вы должны cons элементов в порядке 3 2 1:

(cons 3 '())     ; list is '(3) 
(cons 2 (cons 3 '()))   ; list is '(2 3) 
(cons 1 (cons 2 (cons 3 '()))) ; list is '(1 2 3) 

в тех редких случаях, когда вам нужно добавить еще один элемент в конце (и поверьте мне, делать так, как правило, означает, что вы думаете, алгоритм неправильно), вы можете использовать append, который получает два списка в качестве аргументов:

(append '(1 2 3) '(4)) 
=> '(1 2 3 4) 
Смежные вопросы