Цикл do в ракетке имеет интересную структуру:
(do ([id init-expr step-expr-maybe] ...)
(stop?-expr finish-expr ...)
expr ...)
В документации для r5rs приведен пример:
(let ((x '(1 3 5 7 9)))
(do ((x x (cdr x))
(sum 0 (+ sum (car x))))
((null? x) sum)))
Этот оператор возвращает 25, сумму элементовпетля.x
в цикле do инициализируется в x
в let, а затем итеративно устанавливается в cdr
самого себя каждый раз в цикле.sum
устанавливается в 0 и накапливает значение car
из x
каждый раз до конца.Условие остановки - когда переменная итерации пуста, а возвращаемое значение является суммой.
Хорошо, если не считать предпочтения ракетки в квадратных скобках, это выглядит хорошо.Там есть цикл do и список.Цикл делает что-то над этим списком.Мы можем использовать это, чтобы написать функцию, которая находит конкретный атом в списке (используя квадратные скобки):
(define (find5 lst)
(do ([x lst (rest x)]
[found #f (or found (eq? 5 (first x)))])
((null? x) found)))
Вместо инициализации и добавления значения sum
, I or
в found
.Кроме того, я предпочитаю first
и rest
, а не car
и cdr
и определяю их сам, когда они не существуют.Работа этой функции должна следовать из объяснения примера.
(find5 '(1 2 3 4 6))
Дает #f, как и ожидалось.Аналогично:
(find5 '(1 2 3 4 5 6))
Дает # т.
Можете ли вы обобщить поиск конкретного элемента в списке с помощью цикла do в ваш конкретный вопрос?