#recursion #racket
#рекурсия #ракетка
Вопрос:
У меня возникли проблемы с пониманием того, как создать функцию, которая может принимать ряд одной и той же функции в качестве аргументов с последним аргументом в качестве операнда. Например:
(func sqrt sqrt sqrt 390625)
Приведенный выше вызов должен вернуть 5 как (sqrt 390625) gt; (sqrt 625) gt;gt; (sqrt 25) gt;gt;gt; 5
У меня возникли проблемы с определением точного способа, которым я должен это написать, поскольку любой способ, который я пробовал, приводил к ошибкам или приводил к бесконечному циклу.
Этот код есть до сих пор:
(define func (lambda L (cond ( (equal? (length L) 2) ((car L) (cadr L)) ) ;; If the list consists of only 2 elements, carry out the function (element 1) onto the operand (element 2) ( #t (apply (car L) (func (cdr L))) ) ;; otherwise, apply the function (1st element) onto the rest of the list ) ) )
Первое условие работает, например , возвращает 5, если я звоню (func sqrt 25)
, однако рекурсивный вызов выдает ошибки.
Я был бы признателен за любую помощь в этом.
Комментарии:
1. Если это всегда одна и та же функция, почему вы не получаете функцию
f
и количество разn
, когда хотите ее применить? это будет проще и имеет больше смысла.2. Я знаю, что это был бы более разумный вариант, но некоторое время назад у меня был вопрос на тесте, на который я изо всех сил пытался ответить, поэтому я просто пытаюсь понять это сейчас
Ответ №1:
ОП не дает определения для chain
, так что эта часть неясна, но я думаю, что фундаментальная проблема здесь заключается в том, что нет рекурсивного вызова func
; кроме того, apply
используется не в правильном положении.
Вместо использования (equal (length L) 2)
в качестве базового варианта было бы лучше выполнять рекурсивные вызовы, если первый элемент во входных данных является процедурой, или иным образом просто возвращать элемент:
#lang racket (define multi-call (lambda args (let ((arg (car args))) (if (procedure? arg) (arg (apply multi-call (cdr args))) arg))))
Здесь, когда arg
выполняется процедура, она применяется к результату multi-call
рекурсивного вызова по оставшимся аргументам. Обратите внимание, что multi-call
требуется произвольное количество аргументов, обертывая их в список args
. Шаг сокращения предоставляет (cdr args)
, который представляет собой список оставшихся аргументов. Это означает, что apply
следует использовать для вызова multi-call
оставшихся аргументов, потому multi-call
что ожидает произвольное количество аргументов, а не список аргументов.
multi-call.rktgt; (multi-call sqrt sqrt sqrt 390625) 5