#list #debugging #recursion #scheme #racket
#Список #отладка #рекурсия #схема #racket
Вопрос:
Я писал некоторый код, который выводит список факториалов с учетом списка натуральных чисел. Итак, (список 1 4 3) даст (список 1 24 6). В настоящее время Racket выдает мне ошибку «first: ожидает непустой список; дано: пусто», когда в строке с (cons ……). Я использовал отладчик для проверки, и код никогда не становится пустым, есть ли способ это исправить?
(define (factorialize arr)
(cond
[(empty? arr) empty]
[else (cons (factorial (first arr)) (factorialize (factorial (first (rest arr)))))]))
;;helper function
(define (factorial num)
(cond
[(= 0 num) 1]
[else (* num (factorial (- num 1)))]))
Ответ №1:
Рекурсивный шаг неправильный, почему вы звоните (factorialize (factorial (first (rest arr))))
? это попытка применить factorialize
к результату factorial
, который является числом, а не списком, ожидаемым factorialize
. Вам просто нужно продвинуть рекурсию, вызвав процедуру для остальной части списка! Попробуйте это:
(define (factorialize arr)
(cond
[(empty? arr) empty]
[else (cons (factorial (first arr))
(factorialize (rest arr)))]))
К вашему сведению, более простая и более идиоматичная реализация будет использовать встроенную map
процедуру более высокого порядка:
(define (factorialize arr)
(map factorial arr))
В любом случае, все работает так, как ожидалось:
(factorialize '(1 4 3))
=> '(1 24 6)