Создание функции, которая принимает любое количество функций в качестве

#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