Как сделать ((A.B). (C.D)) в Лисп - PullRequest
5 голосов
/ 15 декабря 2010

Я пытаюсь понять, как это сделать, используя минусы:

((A . B) . (C . D))

, где (A . B) и (C . D) находятся в каждой ячейке cons

Я пытался сделать это (cons (cons 'a 'b) (cons 'c 'd)), но это дает мне это:

((A.B) C . D)

Я тоже попробовал это: (cons (cons 'a 'b) (cons (cons 'c 'd) ())) но это дает мне это:

((A . B) (C . D))

Есть идеи, как этого добиться?

Ответы [ 4 ]

15 голосов
/ 15 декабря 2010

Первый - это то, что вы хотите.Они эквивалентны.Вы можете проверить это следующим образом:

1 ]=> (cons (cons 'a 'b) (cons 'c 'd))

;Value 11: ((a . b) c . d)

1 ]=> (car (cons (cons 'a 'b) (cons 'c 'd)))

;Value 12: (a . b)

1 ]=> (cdr (cons (cons 'a 'b) (cons 'c 'd)))

;Value 13: (c . d)

Запомните список это минус ячейка.«Car» - это элемент head списка или первая половина cons-ячейки, а cdr - остальная часть списка или второй элемент cons-ячейки.

Другой способ убедиться, чтоони эквивалентны:

1 ]=> '((a . b) . (c . d))

;Value 14: ((a . b) c . d)
7 голосов
/ 15 декабря 2010

Просто посмотрите на то, что вы получаете, когда вводите в буквальном смысле ((A . B) . (C . D)):

* '((a . b) . (c . d))

((A . B) C . D)

Существует определенный алгоритм , который принтер Lisp использует для распечатки структур данных, построенных из пар. По сути, вы никогда не сможете получить "минусы", которые будут напечатаны в виде скобок в скобках, когда это CDR другого минуса.

Тем не менее, можно переконфигурировать принтер так, чтобы вы получили требуемое поведение, с помощью SET-PPRINT-DISPATCH :

(set-pprint-dispatch 'cons
  (lambda (stream object)
    (format stream "(~W . ~W)" (car object) (cdr object))))
* '((a . b) . (c . d))

((A . B) . (C . D))
* (cons (cons 'a 'b) (cons 'c 'd))  ;The same object

((A . B) . (C . D))

Хотя, несмотря на это, откровенно говоря, было бы лучше в долгосрочной перспективе, если бы вы научились читать поведение по умолчанию.

0 голосов
/ 15 декабря 2010

То, что вы ищете, невозможно из-за того, как списки представлены в Лиспе. Когда вы создаете список, вы создаете серию cons-ячеек, где car ячейки является значением этого элемента в списке, а cdr является ссылкой на следующую cons-ячейку. Ваша желаемая ячейка, ((A . B) . (C . D)) означает "создать ячейку" против ", где автомобиль равен (A . B), а cdr - (C . D)". Это эквивалентно списку, где первый элемент - (A . B), второй элемент - C, а хвост списка - D или ((A . B) C . D).

0 голосов
/ 15 декабря 2010

Я не совсем уверен, что вы имеете в виду ... Я согласен с приведенным выше комментарием, что последняя строка вашего кода напоминает первую, с которой вы сопоставляете.

Вот неплохой общий ресурс дляВы так или иначе: http://www -2.cs.cmu.edu / ~ dst / LispBook /

...