Как сделать лучший маппер в Scheme используя Streams - PullRequest
1 голос
/ 18 февраля 2009

Реализация схемы в map принимает N + 1 аргумент: процедура из N аргументов и N списков. Кроме того, он завершает сопоставление, когда достигается конец самого короткого списка.

Альтернативой является предоставление значения по умолчанию для каждого списка, который будет рассматриваться как следующий элемент (ы) каждого списка, если он окажется короче, чем остальные.

То есть определить процедуру streem-map, которая принимает в качестве аргументов:
процедура из N аргументов
список из N элементов, который является значением по умолчанию для N-го потока
N потоков

Streem-map создает поток, где первый элемент - это процедура, применяемая к (N) первым элементам потоков, второй элемент - это та же процедура, что и ко вторым элементам потоков, и так далее. Если N-й поток становится пустым, streem-map использует N-й элемент по умолчанию. Следовательно, поток, создаваемый streem-map, всегда будет иметь бесконечную длину; если все N входных потоков имеют конечную длину, в конечном итоге он будет генерировать списки, состоящие из процедура применяется к N значениям по умолчанию.

Например:

(streem-map (lambda (x y z) (* x y z))
‘(0 1 2)
(list->streem ‘(1 2 3))
(list->streem ‘(9 9))
(list->streem ‘(4))

будет генерировать бесконечный поток, состоящий из: ‘(36 36 6 0 0 0…)

Ответы [ 2 ]

2 голосов
/ 04 мая 2009

Давайте сначала определим набор базовых потоковых примитивов, чтобы остальной код имел смысл:

(define-syntax stream-cons
  (syntax-rules ()
    ((stream-cons obj expr)
     (cons obj (delay expr)))))

(define stream-car car)
(define (stream-cdr p) (force (cdr p)))
(define stream-null? null?)

С их помощью мы можем определять операции для «потоков», наших «лучших потоков».

(define (streem-car stream default)
  (if (stream-null? stream) default (stream-car stream)))

(define (streem-cdr stream)
  (if (stream-null? stream) stream (stream-cdr stream)))

(define (streem-map proc defaults . streams)
  (stream-cons (apply proc (map streem-car streams defaults))
               (apply streem-map proc defaults (map streem-cdr streams))))

Вы должны быть в состоянии легко адаптировать это к любой библиотеке потоков, которую вы уже используете. Вам не нужно отдельное преобразование list-> streem, вы можете передавать обычные потоки streem-map (предположительно созданные с помощью list-> stream).

0 голосов
/ 01 октября 2012

Если вы используете потоки SRFI-41 , это просто приложение stream-unfold. Примечание: я автор SRFI-41.

...