Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fp_8.doc
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
116.22 Кб
Скачать

8.3 Бесконечные потоки

Мы рассмотрели хотя и большие, но все-таки ограниченные последовательности данных.

Теперь с помощью потоков попробуем рассмотреть и бесконечные последовательности или, как их обычно называют, - бесконечные потоки.

Дадим LISP-определение, к примеру, бесконечной последовательности единиц:

> (define ones (cons-stream 1 ones))

Это определение выглядит так же, как и определение потока. Его единственное и основное отличие в процедуре получения определяемого значения: поток ничем не ограничен и, следовательно, - бесконечен.

В самом деле, вызов ones возвратит пару, из единицы и обещания вычислить ones, которое, в свою очередь, вызовет … и т.д. и т.п.

Вот мы и получили бесконечный поток единиц.

Естественно, работа с бесконечными потоками требует определённой осторожности.

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

> (elem-no 5 ones)

1

Определим функцию заполнения бесконечного потока целочисленными значениями, начиная с n

> (define (integers-from n)

(cons-stream n (integers-from (+ n 1))))

Теперь определим величину ints как бесконечный поток, заполненный целочисленными значениями начиная с 10

> (define ints (integers-from 10))

И найдем его 5-тый элемент

> (elem-no 5 ints)

14

Поскольку применение функции stream->list к бесконечным потокам бессмысленно, мы определим похожую функцию, скажем initial, возвращающую список из первых n элементов потока.

Это NIL !!

> (define (initial n S)

(if (= n 0) (list)

(cons (head S)

(initial (- n 1) (tail S)))))

>(initial 5 ints)

(10 11 12 13 14)

А теперь – посмотрим на замечательное сложение:

> (initial 5 (stream-add ints ones))

(11 12 13 14 15)

Можно определить на обычных потоках функцию map:

> (define (stream-map proc S)

(if (empty-stream? S) empty-stream

(cons-stream (proc (head S))

(stream-map proc (tail S)))))

И теперь, какая-либо заданная функция proc может работать и на бесконечном потоке. Например, предварительно вспомнив описание sqr, можем получить квадраты элементов бесконечного потока

> (initial 5 (stream-map sqr ints))

(100 121 144 169 196)

Вот определение функции фильтрации на потоках:

> (define (stream-filter pred S)

(cond ((empty-stream? S) empty-stream)

((pred (head S))

(cons-stream (head S)

(stream-filter pred

(tail S))))

(else (stream-filter pred (tail S)))))

Пример получения из бесконечного потока ints (начиная с 10) только 7-ми четных чисел:

> (initial 7 (stream-filter even? ints))

(10 12 14 16 18 20 22)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]