Почему моя функция обратного списка работает сама по себе, но не внутри другой функции?

#functional-programming #scheme #racket #procedural-programming

#функциональное программирование #схема #ракетка #процедурное программирование

Вопрос:

Я пытаюсь вызвать обратную функцию, которую я написал (которая работает при вызове отдельно) внутри другой функции, но она выдает неправильные результаты.

Я пишу программу для получения производной по x от двумерного многочлена. У меня есть основная функция с именем poly_derx, которая будет вызывать две мои вспомогательные функции reverse_list и mult_by_index.

 (define (mult_by_index list_1)
  (if (null? list_1)
      list_1
      (map * list_1 (range (length list_1)))))

(define (reverse_list list_1)
  (if (null? list_1)
      list_1
      (append(reverse (cdr list_1)) (list (car list_1)))))

(define (poly_derx list_1)
  (if (null? list_1)
      list_1
      (reverse_list(cons (mult_by_index (car list_1)) (poly_derx (cdr list_1))))))

(poly_derx `( (1) (1 2 3) () (3)))
  

Опять же, мои 3 функции работают нормально, пока я не добавлю reverse_list в poly_derx. Кроме того, я знаю, что есть встроенный обратный, но я сталкиваюсь с той же проблемой.

На данный момент единственное, что я знаю, что нужно сделать, это попробовать вызвать reverse в разных точках функции, но ничего из того, что я знаю, не работает.

Комментарии:

1. Покажите код, который не работает.

2. возможно, рассмотрите возможность принятия соглашений языка, который вы изучаете, вместо того, чтобы привносить стили / привычки из других языков

3. @Sylwester это код, который не работает

4. Ах. Я думал, вы имели в виду, что она перестала работать, когда вы переместили определение из глобальной процедуры в локальную poly_derx .

5. Пожалуйста, не создавайте больше работы для других людей, вандализируя свои сообщения. Публикуя на Stack Overflow, вы предоставили SO право, не подлежащее отзыву, в соответствии с лицензией CC BY-SA 3.0 для SO, распространять этот контент. Согласно политике SO, любой вандализм будет отменен. Если вы хотите узнать больше об удалении записи, пожалуйста, прочитайте больше на Как работает удаление?

Ответ №1:

Ваша проблема заключается в том, что вы reverse используете значение по умолчанию, и оно вызывается для каждого подсписка от конца до начала. Таким образом, (poly_derx '(1 2 3)) становится (reverse_list (cons res1 (reverse_list (cons res2 (reverse_list res3 (reverse_list '()))))) . Вам нужно только изменить конечный результат. Вы можете сделать это с помощью помощника:

 (define (poly_derx list_1)
  (define (helper list_1)
    (if (null? list_1)
        list_1
        (cons (mult_by_index (car list_1)) (helper (cdr list_1)))))

  (reverse_list (helper list_1)))
  

Также, поскольку списки создаются от конца к началу и повторяются от начала до конца, вы можете использовать это для обратного списка в помощнике.

 (define (poly_derx list_1)
  (define (helper list_1 result)
    (if (null? list_1)
        result
        (helper (cdr list_1) (cons (mult_by_index (car list_1)) result))))

  (helper list_1 '()))
  

Поэтому обратите внимание, что вы не можете применить процедуру, которую вы хотели бы выполнить один раз для каждой итерации. Это даст неожиданные результаты.

Комментарии:

1. Итак, я подумал, что она не вызовет обратный вызов, пока функция в ее аргументе не будет завершена.

2. @BobDole Он не делает различий между вызовом самого себя или вызовом чего-то другого. Все в if выражениях then или else выполняется полностью.