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