Разница в лиспе между (cons 'a (cons 'b 'c)) и (cons 'a '(b.c))
Вопрос
В чем разница между:
(cons 'a (cons 'b 'c)) ;; (A B . C)
и
(cons 'a '(b.c)) ;; (A B.C)
Мне нужно создать следующий список ((a.b).c) используя cons, поэтому я пытаюсь понять, что представляет это ".".
L.E.:У меня есть следующее (cons (cons 'a 'b) 'c)
но это производит ((A . B) . C)
и не ((A.B).C)
(Обратите внимание на дополнительные пробелы)
Решение
Пробелы используются для разделения лексем списка. A.B
это единственный токен. (A.B)
представляет собой список с одним элементом. (A . B)
является ячейкой cons с A
как автомобиль и B
как cdr.
Ячейка cons - это пара "вещей" (objects).В вашем случае эти вещи являются символами, и они названы A
, B
, и т.д..Печатное представление такой ячейки является (A . B)
, например.Это называется "точечная нотация".Первый элемент называется "car", второй "cdr".
Функция cons
создает такую ячейку. (cons 'a 'b)
таким образом, образуется клетка (A . B)
. Обратите внимание, что имена всегда отображаются внутри.
Скорее всего, это то, чего хотел ваш учитель, так что ((A . B) . C)
это правильный вывод, а ваш код - правильный ответ.Это ячейка, в которой автомобиль указывает на другую ячейку, а cdr содержит C
.Эта другая ячейка - это ячейка, в которой автомобиль содержит A
и cdr B
.
Кстати, в Список представляет собой линейную цепочку таких ячеек cons, так что car всегда содержит значение, а cdr указывает на остальную часть списка.Последний cdr указывает в никуда (что в Lisp называется NIL).В точечной нотации список представляет собой, например (A . (B . (C . NIL)))
.Поскольку списки важны, их можно написать короче следующим образом: (A B C)
.Если последний CDR имеет значение вместо NIL, оно отображается в точечной записи, например (A . (B . (C . D))))
может быть записан как (A B C . D)
.
Другие советы
.
между двумя символами находится часть символа. b.c
представляет собой символ с названием, состоящим из трех символов: b, ., и c.
Если вы войдете FOO.BAR
, тогда Lisp прочитает его как один символ.
Если вы войдете (FOO.BAR)
затем Lisp прочитает его как список с одним символом в качестве содержимого.
Если вы войдете (FOO . BAR)
тогда Lisp прочитает это как ячейку cons с FOO
в качестве Автомобиль и BAR
в качестве CDR.
.
используется для разделения Автомобиль и тот CDR из ячейки cons: (a . b)
.Обратите внимание на пространство вокруг .
.
(cons 'b 'c)
создает ячейку cons с символом b
в качестве Автомобиль и символ c
в качестве CDR.Это записывается как (b . c)
.
(cons 'a '(b.c))
создает список из двух символов, a
и b.c
.Это записывается как (a b.c)
.
((A.B).C)
всегда печатается как ((A.B) . C)
.Это также не список.
((a.b) . c)
является ячейкой cons со списком (a.b)
в качестве Автомобиль и символ c
в качестве CDR.
Если это происходит в процессе изучения lisp, то вопрос, вероятно, не подразумевал правила "не допускается использование пробелов", поскольку пробелы не имеют значения перед круглыми скобками, и правильный ответ - тот, который вы дали.
В частности, пробел после закрывающей круглой скобки добавляется всегда, но это исключительно для удобства чтения человеком.Не имеет никакого смысла требовать, чтобы он не печатался.