Элемент минусов для списка против списка минусов для элемента в схеме

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

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

Спасибо!


person Maritha Wang    schedule 06.10.2013    source источник
comment
Ответ @ ÓscarLópez объясняет это довольно хорошо. Полезно понимать, что в семействе языков Lisp не совсем правильно думать о cons как об операции list. Языки Lisp обычно имеют cons-ячейки как настоящие типы данных, а затем реализуют списки как намеренные типы данных. То, что мы называем списками, является списками по соглашению. Я упомянул об этом в более раннем ответе, описывая, как мы часто можем использовать ячейки для реализации списков, но как мы можем также использовать ячейки для реализации других структур, таких как деревья.   -  person Joshua Taylor    schedule 07.10.2013
comment
Страница @JoshuaTaylor не найдена.   -  person Han Qiu    schedule 09.08.2016
comment
@hanQiu Думаю, этот вопрос удалили. Но теперь в документации SO есть раздел, который охватывает ту же идею: списки по соглашению   -  person Joshua Taylor    schedule 09.08.2016
comment
Эта документация также была удалена :(   -  person Óscar López    schedule 20.02.2019


Ответы (1)


Примитив cons просто склеивает две вещи, и тот факт, что некоторые из этих вещей считаются списками, является случайным. Например, это работает и создает пару (также известную как 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)
person Óscar López    schedule 06.10.2013