Как написать функции функций в схеме - PullRequest
0 голосов
/ 25 февраля 2019

Я должен написать функцию с именем (nth-filtered f n), где f - это функция одной переменной, а n - натуральное число, которое вычисляет n-е натуральное число, так что f, примененное к этому числу, равно #t.

Если бы мы позвонили (nth-filtered even? 1), мы получили бы 2

(nth-filtered prime? 10), мы бы получили 29

Как мне сделать так, чтобы он работал для любого последовательногофункционировать?О чем мне следует думать, когда я подхожу к проблеме такого типа?

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

Ваша проблема требует фолда, который является стандартным способом итерации по списку, сохраняя при этом записи о проделанной работе.

Здесь очень грубый метод, использующий для / fold :

(define (nth-filtered predicate index)
  (for/fold ([count 0]
             [current #f] #:result current)
            ([n (in-naturals 1)]) ; we start at 1 but we could start at 0
            #:break (= count index)
    (values (if (predicate n) (add1 count) count)
            n)))

for/fold принимает список начального состояния.Здесь мы определяем count как количество раз, которое данный предикат возвратил #t и current как проверенное в данный момент значение.

Затем он принимает список итераторов, в этом случае мы повторяем только бесконечно(in-naturals).

Чтобы остановить его, мы предоставляем условие #:break, когда «количество истинных предикатов (count) равно запрошенной сумме (index)».

for/fold запрашивает, чтобы его тело заканчивалось списком значений для каждой переменной "состояния", чтобы обновить их для следующей итерации.Здесь мы предоставляем два значения: одно - новое count, другое - просто текущее n.

Вы можете попробовать его, оно работает так, как вы просили:

> (nth-filtered even? 1)
2
> (require math/number-theory)
> (nth-filtered prime? 10)
29
> (nth-filtered prime? 5)
11
0 голосов
/ 25 февраля 2019

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

например.

(define (double fun) 
  (lambda (value) 
    (fun (fun value))))

(define (add1 v)
  (+ 1 v))

(define add2 (double add1))

(add2 1) ; ==> 3

Теперь в договоре не сказано, поэтому вы вычитаете, посмотрев, что вы делаете (fun ...), что fun должна быть функцией.Представьте себе:

(define test (double 5)) ; probably works OK
(test 1) 

Последний сбой, так как вы получаете application: 5 is not a procedure или что-то подобное.Сообщение об ошибке не стандартизировано.

Как атаковать вашу задачу, создав помощника, который имеет те же аргументы, что и ваша функция, но кроме того, текущее число, которое, как я полагаю, начинается с 1. Как я показал, вы используете переменную функции в качестве функции и рекурсиввсегда увеличивая число и уменьшая n, когда f был #t.Фактическая функция будет просто использовать помощника, передавая все параметры в дополнение к вашей переменной состояния.

...