2015-12-08 6 views
0

Я хочу создать функцию, которая могла бы прочитать мои 2 входных списка и объединить то, что находится внутри списков, в 1 список, что позволяет мне использовать этот 1 список для другой функции.Lisp: Как использовать функцию let для объединения 2 списков в 1 список?

Я пытался использовать пусть функцию

(defun sumup(p1 p2) 
    (let ((sum (append(list p1 p2)))) 
     (format t "the sum is ~a" sum) 
     (poly sum) 
    )) 

и когда я вхожу входной список

(sumup+ '(5 (x 2)) '(3 (x 2))) 

это дает результаты, как

the sum is ((5 (x 2)) (3 (x 2))) 
    the poly term is (8 (x 2)) 

Вот функция поли, которая прочитает список ввода и добавит.

 (defun poly (p1) 
     (let((x1(car(car(cdr(car p1))))) (x2(car(car(cdr(car(cdr p1)))))) 
      (e1(car(cdr(car(cdr(car p1)))))) (e2(car(cdr(car(cdr(car(cdr p1))))))) 
      (c1(car(car p1))) (c2(car(car(cdr p1)))) 
      (remainder(cdr(cdr p1))) 
      ) 
     (if(and(null remainder)(null c2)) 
      (format t "the poly term is (~a (~a ~a))" c1 x1 e1) 
      ) 

     (if(and(equal x1 x2)(equal e1 e2)) 
      (poly(append (list(list(+ c1 c2)(list x1 e1))) remainder))) 

      ) 
      ) 

так с этой функцией поли

(poly '((5(x 3))(3(x 3))(1(x 3))(4(x 3)))) 

вы получите

the poly term is (13 (x 3)) 

поэтому мой выбранный формат для представления 5x^2 будет (5 (х 2)), поэтому я цитирую.

функция sumup способна объединить 2 условия, но если

(sumup+ '(5 (x 2)) '((3 (x 2)) (2 (x 2)))) 

я получу

the sum is ((5 (x 2)) ((3 (x 2)) (2 (x 2)))) 

, как я могу изменить его, чтобы быть ((5 (x 2)) (3 (x 2)) (2 (x 2)), которые могут быть использованы для poly функции?

+1

'sum' - лексическая переменная, которая является локальной формой' let' в функции 'sumup' и частной для нее. Это означает, что переменная 'sum' видна только формам, содержащимся внутри формы' let', которая связывает переменную. 'sum' не видна за пределами' let', и поэтому она не видна вне функции, которая содержит let. 'let' does ** not ** mean *" пусть будет известно, что этот символ ссылается на это значение ** везде ** в этой программе "*.Для этого вы можете использовать глобальную переменную ('defvar',' defparameter', 'defconstant'). – Kaz

+0

Спасибо за объяснение, извините, я не дал понять, как выше код, который я хотел показать, я думал, что сумма будет работать как список. Я попытался использовать сумму в функции sumup и создать форму, и все же SUM не является списком. – mesue

+0

Что делает 'poly'? Замените 'poly' на' listp' и 'T', что означает, что' sum' - это, по сути, список (проверенный в .CLISP 2.49) – 8bittree

ответ

0

Предполагая, что defun подразумевает общий lisp. Добавляется значение here.

((5 (x 2))) - это список, содержащий список (5 (x 2)).

Я подозреваю, что вы ищете

(sumup (5 (x 2)) (3 (x 2))) 

С другой стороны, поли вызывается с котировальный список одного аргумента, так что возможно, вы на самом деле хотите:

(poly sum) 

Общая , Я думаю, нам нужно увидеть поли. Я не понимаю, почему вы цитируете все.

+0

спасибо за помощь, причина цитаты в том, что я хочу сохранить все в форме как (константа (постоянная)), это мой выбранный способ представления термина типа 5x^2 (5 (x 2)), поэтому в основном, поли будет сравнивать мощность и срок, чтобы проверить, являются ли они одинаковыми и делают дополнение. поэтому вышеупомянутая проблема основана на моем синтаксисе – mesue

1

Выражение '(sum) обозначает литерал списка. Это сокращение для оператора quote и означает то же самое, что и (quote (sum)).

Оператор котировки подавляет оценку своего аргумента как выражения и выражает аргумент буквально; то есть это означает «не пытайтесь вызвать функцию с именем sum, просто дайте мне фактический список (sum): один список элементов, содержащий символ sum».

Так, например, (quote (+ 2 2)) или, используя обычную стенопись, '(+ 2 2) возвращает (+ 2 2), буквально.Если мы отбросим цитату и оценим (+ 2 2), тогда получим 4.

Теперь, если мы возьмем '(sum) и просто уронить цитату, он не будет работать, потому что теперь мы оцениваем форму (sum), выражающую вызов функции, имя которой sum, без аргументов. Конечно, такой функции нет, поэтому вызов ошибочен.

В Lisp есть особый вид «активированной цитаты», которая напоминает обычную цитату. Он называется backquote. Чтобы использовать обратную кавычку, мы заменяем апостроф ' стенографией с обратным адресом: `.

Как цитата, backquote подавляет оценку. Тем не менее, внутри обратной кавычки, мы можем указать элементы, которые являются исключениями из правила «не оценивать», предварив их с запятой, например:

`(,sum) 

Если мы имеем переменную sum, которая содержит список (или любой другой объект), и в этой области мы оцениваем приведенный выше обратный отсчет, этот обратный отсчет будет вычислять список одного элемента, который содержит этот объект. Точно так же, как если бы мы оценили выражение (list sum).

Более сложный quasiquote пример:

(let ((a "hello") 
     (b 42)) 
    `(1 2 3 ,a 4 ,b b ,(+ 2 2) (+ 2 2))) 

-> (1 2 3 "hello" 4 42 b 4 (+ 2 2)) 

Объекты внутри обратной кавычки не предшествует запятой все взяты буквально: b не вычисляется в качестве переменной, но остается b, в (+ 2 2) пребывания (+ 2 2) и ISN» t уменьшено до 4, в отличие от ,(+ 2 2).

Кстати, внутри функции poly, у вас есть это выражение:

(append (list (list (+ c1 c2) (list x1 e1))) remainder) 

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

`((,(+ c1 c2) (,x1 ,e1)) ,@remainder) 

Все отвлекают загромождали из append и list звонков уходит, и мы просто видим форму списка строится.

Техническое примечание: backquote не является сокращением для любого конкретного синтаксиса формы в Common Lisp. В то время как 'X означает (quote X), как обсуждалось, `X не имеет такого соответствия; как это работает, отличается в разных реализациях Common Lisp. У запятой также нет специального синтаксиса. На диалекте Лиспа, известном как Схема, `X соответствует (quasiquote X) и ,Y соответствует (unquote Y). Это определяется языком Схемы, и так происходит во всех реализациях. Backquote также известен как «quasiquote», особенно среди программистов Scheme.