Точечная запись в схеме

Я новичок в программировании Схемы. Я знаю, что точечная нотация в Схеме используется для представления пары символов, например '(a . b) .

Первым элементом может быть символ или список, это не имеет значения. Но особенно второй элемент должен быть символом, если это не так, может быть, например, списком, то мы не можем создать пару со встроенной процедурой cons .

Так можно ли создать пару из 2 списков ??? Ну, я думаю, что решение состоит в том, что преобразование списка в символ, но на самом деле это две совершенно разные вещи – невозможно, как я понимаю.

Это код, который я написал:

 (define compare-attrs (lambda (attribute1 attribute2) (if (or (and (null? attribute1) (null? attribute2)) (and (not (null? attribute1)) (not (null? attribute2)))) (cons attribute1 attribute2) #f))) 

В которой атрибут1 и атрибут2 являются 2 списками, а мой вывод:

 attribute1 atrribute2 

Ожидаемый результат: ‘(атрибут1. Attribute2)

Пожалуйста, объясните это. Заранее спасибо!!!

EDIT: добавление функции compare-attrs

Функция compare-attrs, используемая для извлечения части, которая описывает атрибуты сущностей, и позволяет им создать пару, сущности, определенные ниже:

 (entity e0 (prov:label "entity e0") (entity e1 (prov:location "London") 

поэтому атрибут этих объектов (prov:label "entity e0") и (prov:location "London") . При применении функции compare-attrs, поскольку эти атрибуты не являются null , так что вывод, который я ожидаю,

 `(prov:label "entity e0") . (prov:location "London")` 

Примечание: это cannibalized из ответа на рекурсивный диапазон в Lisp добавляет период? , который действительно задает другой вопрос. Однако объяснение того, как печатаются пары, одинаково. Остальная часть ответа различна.

У вашего вопроса есть немного недоразумений, но я думаю, что мы можем это прояснить.

Первый [аргумент cons ] может быть символом или списком, это не имеет значения. Но особенно второй элемент должен быть символом, если это не так, может быть, например, списком, то мы не можем создать пару со встроенной процедурой cons.

Это неверно. Вы можете вызывать cons с любыми аргументами, которые вам нравятся, и вы всегда будете возвращать ячейку cons чей car такой же, как первый аргумент cons , и чей cdr совпадает с вторым аргументом cons . То есть единственное, что важно для cons – это то, что оно удовлетворяет уравнениям

 (eq? a (car (cons ab)) (eq? b (cdr (cons ab)) 

Так можно ли создать пару из 2 списков ??? Ну, я думаю, что решение состоит в том, что преобразование списка в символ, но на самом деле это две совершенно разные вещи – невозможно, как я понимаю.

Это вполне возможно; если у вас есть два списка, например, list1 и list2 , вы можете создать пару, чей car является list1 и чей cdr является list2 просто вызывая (cons list1 list2) . Теперь я думаю, что проблема, с которой вы столкнулись, состоит в том, что вы ожидаете увидеть ( . ) в качестве вывода, и вы видите некоторые разные. Чтобы объяснить, почему это так, нам нужно понять, как списки представлены в Lisps и как печатаются пары.

Список в Схеме – это либо пустой список () (также известный как nil в некоторых Lisps), либо ячейка cons, чей car (также известный как first ) является элементом списка и чей cdr (также известный как rest ) является либо остальную часть списка (т. е. другой список) или атом, который завершает список. Обычный терминатор – пустой список () ; списки, завершенные () называются «правильными списками». Списки, завершенные любым другим атомом, называются «неправильными списками». Список (1 2 3 4 5) содержит элементы 1, 2, 3, 4 и 5 и заканчивается символом () . Вы можете построить его

 (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ()))))) 

Теперь, когда система печатает ячейку cons, общий случай заключается в ее печати

 (car . cdr) 

Например, результат (cons 1 2) печатается как

 (1 . 2) 

Поскольку списки построены из cons cons, вы также можете использовать это обозначение для списков:

 '(1 2 3 4 5) == '(1 . (2 . (3 . (4 . (5 . ()))))) 

Это довольно неуклюже, поэтому большинство lisps (все, что я знаю) имеют особый случай для печати cons-ячеек: если cdr является списком (либо другой cons-ячейкой, либо () ), тогда не печатайте . , и не печатайте окружную скобку cdr (которую в противном случае она имела бы, так как это список).

Теперь мы можем объяснить, почему результат (cons list1 list2) не выглядит ( . ) . Если вы называете cons двумя списками, вы возвращаете пару с ожидаемым car и cdr , но он не печатается с помощью . нотации. Например,

 (cons '(1 2 3) '(abc)) ;=> ((1 2 3) . (abc)) ; which is typically *printed* as ;=> ((1 2 3) abc) 

Но опять же, печатное представление на самом деле не имеет значения, если учесть следующие уравнения:

 (eq? a (car (cons ab)) (eq? b (cdr (cons ab)) 

Конечно же:

 (car (cons '(1 2 3) '(abc))) ;=> (1 2 3) (cdr (cons '(1 2 3) '(abc))) ;=> (abc) 

В конкретном примере, о котором вы спрашиваете, подумайте, что происходит, когда вы звоните

 (cons '(prov:label "entity e0") '(prov:location "London")) 

В результате, фактически,

 ((prov:label "entity e0") . (prov:location "London")) 

но из-за правил печати это печатается как

 ((prov:label "entity e0") prov:location "London") 

Тем не менее, вы все равно можете получить два атрибута, используя car и cdr :

 (car '((prov:label "entity e0") prov:location "London")) ;=> (prov:label "entity e0") (cdr '((prov:label "entity e0") prov:location "London")) ;=> (prov:location "London") 

и это все, что вам действительно нужно, чтобы иметь возможность сделать это позже.

Точечная нотация в Схеме или любой другой диалект LISP используется для создания точечной пары любых двух значений. Значения могут быть либо символами, либо списками, либо чем-либо еще. Неважно, какая это ценность. Например:

 '(author . aaditmshah) => (author . aaditmshah) '((abc) . (def)) => ((abc) def) 

Как вы можете видеть, если вы создаете пунктирную пару из двух списков, тогда первый список будет добавлен в заголовок второго списка. Это связано с тем, что списки в LISP являются вложенными пунктирными парами:

 '(a . (b . (c . ()))) => '(abc) 

Следовательно, когда вы пишете '((abc) . (def)) , вы пишете следующее:

 '((abc) . (d . (e . (f . ())))) => '((abc) def) 

Это совершенно верно. Вы можете получить доступ к обоим спискам отдельно, используя car и cdr как обычно:

 (car '((abc) . (def))) => (abc) (cdr '((abc) . (def))) => (def) 

Я не уверен, что ваша функция compare-attrs должна делать. Ваша ветка if возвращает ячейку cons тогда как ветка else возвращает логическое значение. Для меня это не имеет никакого смысла. Тип возвращаемой функции должен быть постоянным.

Возможно, вы неправильно сформулировали свой вопрос, потому что я не совсем уверен в вашей проблеме. Дайте мне знать, если у вас все еще есть сомнения.

Мое воспоминание о структурировании данных в схеме заключается в том, что вы предпочли бы избегать пунктирной пары атомов (т (a . b) Е. (A. (a . b) ), поскольку это представляет собой результат сочетания двух атомов вместе. Если вы посмотрите в разделе «Маленькая схема» , стр. 3, вы увидите следующее:


Закон о противодействии

Примитивные минусы принимают два аргумента. Второй аргумент cons должен быть списком. Результатом является список.


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

Итак, скажем, что вы хотите иметь кортеж – вы можете сделать его похожим на (ab) что вполне разумно. Тогда вы можете написать следующие функции:

 (define (make-tuple ab) (list ab)) (define (tuple-first tup) (car tup)) (define (tuple-second tup) (car (cdr tup))) (define (tuple? tup) (and (list? tup) (eq? 2 (length tup)))) 

который теперь дает мне функции доступа и конструктор, и я – золото. Но это не означает, что это единственный способ сделать это. Вы можете пойти прямо вперед и использовать пары тоже:

 (define (make-tuple ab) (cons ab)) (define (tuple-first tup) (car tup)) (define (tuple-second tup) (cdr tup)) (define (tuple? tup) (pair? tup)) 

Поэтому в вашем коде вы можете использовать конструктор здесь, чтобы сделать кортеж, который вы хотите.

В общем, ваша функция compare-attrs нечетна в том, что имя действительно не дает нам представления о том, что вы пытаетесь сделать. Я был бы более склонен писать так:

 (define (compare-attrs a1 a2) (or (and (null? a1) (null? a2)) (and (not (null? a1)) (not (null? a2))) )) (define (join-populated-attrs a1 a2) (if (compare-attrs a1 a2) (make-tuple a1 a2) '())) 

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

Я также должен сказать, что если вы хотите, чтобы результат отображался определенным образом, вы, вероятно, также должны писать print-tuple .

  • где можно найти xsd.exe в visual studio 2013 на windowsх 8
  • Какой пакет lang подходит для SICP в Dr.Racket?
  • Как отменить конкретную миграцию?
  • Spring v3 нет объявления для элемента 'mvc: resources'
  • «Приложение: не процедура» в двоичных арифметических процедурах
  • В чем разница между цитатой и списком?
  • Как сгенерировать диаграммы UML (особенно диаграммы последовательности) из кода Java?
  • В чем разница между eq ?, eqv ?, equal ?, и = в схеме?
  • Неожиданное сохранение данных
  • Сохранение дополнительных данных с заказом в Magento
  • Рекурсивный диапазон в Lisp добавляет период?
  • Давайте будем гением компьютера.