Racket «first: ожидает непустой список; дано: пусто»

#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)