Что делает оператор (define ...)
в lenght
, так это создает новую переменную с именем "index", которая имеет более локальную область действия, чем "index", который вы определили в верхней части. Это только поверхностная проблема - что более важно, похоже, что вы пытаетесь написать код на C, используя Scheme. В таком простом домашнем задании вы должны , а не использовать глобальные переменные, и вам никогда не придется менять переменную после ее создания. Многим программистам трудно изменить свое мышление при первом изучении функционального программирования.
То, как вы написали lenght
- это не столько рекурсия, сколько просто прославленный цикл while! Нет смысла в рекурсии, если (lenght x)
снова вызывает только (lenght x)
. Например, вот как я бы написал digits
, чтобы подсчитать, сколько цифр в 10-значном числе:
(define digits
(lambda (n)
(letrec ([digit-helper (lambda (n index)
(if (= (modulo n (expt 10 index)) n)
index
(digit-helper n (add1 index))))])
(digit-helper n 0))))
Обратите внимание, как я никогда не изменяю переменную после ее создания, а только каждый раз создаю новые переменные. Поскольку мне нужно отслеживать индекс, я создал вспомогательную функцию digit-helper
, которая принимает два аргумента, чтобы скрыть тот факт, что digit
принимает только один аргумент.