Почему использование cons для создания пары из двух списков создает список и два элемента? - PullRequest
5 голосов
/ 11 июня 2010

Я начал изучать Scheme, в основном для удовольствия, и потому что раньше никогда не использовал функциональный язык. Я выбрал Схему, потому что давно хотел прочитать SICP .

В любом случае, я сейчас изучаю списки, а до этого я узнал о минусах, машине и CDR. И есть пример, который создает список списков с минусами, например:

(cons (list 1 2) (list 3 4))

Результирующий список ((1 2) 3 4), который не имеет смысла для меня, я ожидаю ((1 2) (3 4)) будет результат (список, составленный из двух списков ). Почему он так себя ведет? Я понимаю, что если бы я использовал машину, я бы получил (1 2), и CDR я бы получил (3 4), потому что CDR всегда возвращает «остальное», но я не понимаю, почему список не составлен из двух списков?

Ответы [ 4 ]

9 голосов
/ 11 июня 2010

Вы получаете список с (1 2) в качестве первого элемента (автомобиль) и (3 4) в качестве остальных (cdr), потому что первый аргумент для cons является первым элементом списка, а второй аргумент является списком содержит оставшиеся предметы.

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

Если второй аргумент cons станет вторым элементом списка, как бы вы создали список с тремя аргументами? Вам нужно будет сделать cons variardic, после чего это будет просто другое имя для list.

Если вы хотите создать список списков, используйте (list (list 1 2) (list 3 4)).

3 голосов
/ 11 июня 2010
(list (list 1 2)
      (list 3 4))

совпадает с

(cons (list 1 2)
      (cons (list 3 4)
            '()))

Что приводит к

((1 2) (3 4))

, который также можно записать как

((1 . (2 . ()))
 . 
 ((3 . (4 . ()))
  .
  ()))
1 голос
/ 11 июня 2010
list A:  [  |      ]
          1   [ | ]
               2 /

list B:  [  |      ]
          3   [ | ]
               4 /

======================

(cons A B)

[           |           ]
 [  |     ]   [  |     ]
  1  [ | ]     3  [ | ]
      2 /          4 / 

Графическое представление внутренних структур может помочь нам визуализировать проблему.

И это поможет еще немного:

[           |           ]
     X        [  |     ]
               3  [ | ]
                   4 / 

Вы видите образец? Выше приведен список (X 3 4). По этой причине (cons A B) рисует только часть car в виде отдельного списка, а не cdr.

0 голосов
/ 16 июня 2010

Поскольку cons-ячейка является , а не списком из двух элементов, эти два часто путаются.Если (a . b) является конс-ячейкой, то (a . (b . ())) является списком из двух элементов.Любой список, за исключением пустого списка, в частности, является cons-ячейкой, поле car которой содержит первый элемент, а поле cdr содержит список, который содержит остальные элементы.Таким образом, список - это просто двоичное дерево, крайний правый лист которого является специальной константой () или nil в зависимости от вашего диалекта.

Именно поэтому (cons 0 '(1 2 3)) оценивается как (0 1 2 3), а не (0 (1 2 3)) мы создаем cons-ячейку с автомобилем 0 и cdr (1 2 3), поэтому список (0 1 2 3).

...