Как изменить схему переменных

Я пытаюсь суммировать список, используя изменяемые объекты для задания. letиспользуется здесь, чтобы позволить мне изменять x общую сумму и counter. Я не очень хорошо разбираюсь в схеме, поэтому использую операторы if для каждого числа в списке lst:

(define lst (list 1 2 3 4 5))

(let mut ((counter 0))
 (let ((x (car lst)))

  (if (= counter 4)
      x)
  (if (= 0 counter)
    (+ x (cadr lst)))
  (if (= 1 counter)
      (display (caddr lst)) ;test
      (+ x (caddr lst)))
  (if (= 2 counter)
      (+ x (caddr lst)))  

  (set-car! lst (cdr lst))   
  (mut (+ counter 1))
  )
)

однако когда я запускаю код, я получаю сообщение об ошибке

+: contract violation
      expected: number?
      given: (mcons 2 (mcons 3 (mcons 4 (mcons 5 '()))))
      argument position: 1st
      other arguments...:

Однако, когда я проверяю (caddr lst), он возвращает 3, как и ожидалось. Моя проблема заключается в том, почему при запуске caddr выдает (mcons 2 (mcons 3 (mcons 4 (mcons 5 '())))) при применении к +, а когда не применяется, возвращает 3

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


person Artemis    schedule 10.03.2018    source источник
comment
Откройте интерпретатор. Напишите (define ls '(1 2 3 4)). Осмотрите (car ls) и (cdr ls). Напишите (set-car! ls (cdr ls)). Осмотрите (car ls) и (cdr ls) еще раз.   -  person molbdnilo    schedule 11.03.2018
comment
Вы пропустили основы Scheme и пытаетесь написать программу на другом языке. Начните сначала с главы 1. ((if (= counter 4) x) не совпадает с if x == 4: return x.)   -  person molbdnilo    schedule 11.03.2018
comment
@molbdnilo У меня сложилось впечатление, что car возвращает число, а не ссылку, не так ли?   -  person Artemis    schedule 11.03.2018
comment
Ссылок на схему нет. SICP доступен бесплатно в Интернете.   -  person molbdnilo    schedule 11.03.2018


Ответы (1)


Итак, я понял, что использование совершенно другой реализации @molbdnilo было правильным, что мое понимание было ошибочным. вот моя реализация, если кто-то еще борется с этой проблемой

(define (goMut)
  (define mVar 0)
  (define acc 0)

(define (accDo num)
    (set! acc (+ num acc)))

  (for-each (lambda (x) (set! mVar x) (accDo x))
            (list 1 2 3 4 5))
  acc
)

Используя набор! мы можем применить значение из списка к внешней переменной и изменять его по мере прохождения цикла с помощью функции accDo. Шаблон функции взят из SICP стр. 107

person Artemis    schedule 11.03.2018
comment
if в исходном коде должны были быть вложены, вот так. конечно, такую ​​цепочку вложенных if лучше закодировать с помощью cond. здесь вы используете готовый for-each , но изначально вы сами выполняли итерацию. (лучше так учиться?) - person Will Ness; 12.03.2018