#scheme #lisp
#схема #lisp
Вопрос:
То, что я пытаюсь сделать, заключается в следующем:
Мне нужно создать функцию, которая добавляет значение в словарь в scheme, поэтому я определил словарь как список списков следующим образом:
(define Dictionary '(("key 1" "value 1") ("key 2" "value")))
Теперь о функции, которая добавляет значения:
Прежде всего, я проверяю, не является ли элемент null и имеет ли элемент ключ и значение, прежде чем пытаться добавить его в список
(define (addElement element mylist)
(cond
((null? elemment) 'The_Element_Is_Null)
((null? (cdr element)) 'The_Element_is_singleTon)
(#t (cons element mylist))
)
)
И попробуйте выполнить это следующим образом:
(addElement '("key 3" "value 3") Dictionary)
и DrRacket выполняет код, который выводит следующее
(("key 3" "value 3") ("key 1" "value 1") ("key 2" "value"))
Обратите внимание, что при использовании cons значение отображается так, как если бы оно было добавлено в список, но значение таковым не является, аналогично другим языкам, где возможно напечатать что-то подобное этому
int i = 1;
print("value = " i 5);
программа должна напечатать
value = 6
но на самом деле значение переменной равно 1. таким же образом, мой словарь не получает новых значений, и выполнение этого кода просто выводит список с новым элементом, но элемент на самом деле не добавлен в список
Одно из решений, которое я попробовал, — это использование метода set! чтобы попробовать добавить значение, но я получаю тот же результат
(define (addElement element mylist)
(cond
((null? elemment) 'The_Element_Is_Null)
((null? (cdr element)) 'The_Element_is_singleTon)
(#t (set! myList(cons element mylist)))
)
)
Комментарии:
1. Вы абсолютно уверены, что эта функция должна изменять словарь? Гораздо чаще встречается функция, которая возвращает новый словарь, похожий на старый, но с добавленным элементом. (Используется как
(define new-dict (add-element '("this" "that") old-dict))
.)2. Это было именно то, что мне было нужно
Ответ №1:
В Scheme большинство операций со списком, которые «изменяют» список (например: cons
), на самом деле не обновляют список ввода, вместо этого они создают новый список, и вы должны сохранить его или передать вместе.
Если вы хотите, чтобы изменение списка, внесенное внутри процедуры, было сохранено после завершения процедуры, вы должны явно set!
изменить список — ваша вторая попытка направлена в правильном направлении, но вы просто устанавливаете параметр процедуры, а не исходный список. Я предлагаю две альтернативы:
; declare the list outside the procedure
(define Dictionary '())
; 1) either set! the list inside the procedure
(define (addElement element)
(cond
((null? element) 'The_Element_Is_Null)
((null? (cdr element)) 'The_Element_Is_Singleton)
(else (set! Dictionary (cons element Dictionary)))))
(addElement '("key 1" "value 1"))
; 2) or set! the list with the result of calling the procedure
(define (addElement element myList)
(cond
((null? element) 'The_Element_Is_Null)
((null? (cdr element)) 'The_Element_Is_Singleton)
(else (cons element myList))))
(set! Dictionary (addElement '("key 1" "value 1") Dictionary))
Имейте в виду, что в целом использование этого стиля процедурного программирования set!
сильно не рекомендуется — то, что вы хотите сделать, это передать результат вызова процедуры, которая изменяет список, другой процедуре (состав функции) или той же процедуре (как часть рекурсии) и позволить ей обработать новый результат. Помните, что Scheme — это функциональный язык программирования по своей сути, и все делается не так, как вы привыкли.
Комментарии:
1. @D.Shinoda Это ответило на ваш вопрос? если это так, пожалуйста, не забудьте принять это, просто нажмите на галочку слева от него 😉
2. Эй, только что нашел другой способ, который устраняет необходимость set! , использование (define ()) для переопределения списка с выводом моей функции было тем, о чем было назначение, но в любом случае спасибо