2015/12/07
SICP 問題 3.50
マクロを使ってる部分は
ストリームの実装と問題3.50-3.51 - nrvctの日記
ここから引用.
;; 次の二つは引用元から
;; cons-streamは評価順序を変えたいのでマクロ
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))
;; delayもマクロ.マクロよくわかってない.
;; メモ化する.
(define-syntax delay
(syntax-rules ()
((_ exp) (memo-proc (lambda () exp)))))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream (proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-for-each proc s)
(if (stream-null? s)
'done
(begin (proc (stream-car s))
(stream-for-each proc (stream-cdr s)))))
(define (display-stream s)
(stream-for-each display-line s))
(define (display-line x)
(newline)
(display x))
(define (stream-null? stream)
(null? stream))
(define the-empty-stream '())
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream
low
(stream-enumerate-interval (+ low 1) high))))
(define (stream-filter pred stream)
(cond ((stream-null? stream) the-empty-stream)
((pred (stream-car stream))
(cons-stream (stream-car stream)
(stream-filter pred
(stream-cdr stream))))
(else (stream-filter pred (stream-cdr stream)))))
(define (force delayed-object)
(delayed-object))
(define (memo-proc proc)
(let ((already-run? false) (result false))
(lambda ()
(if (not already-run?)
(begin (set! result (proc))
(set! already-run? true)
result)
result))))
;; 3.50
;; stream-map
(define (stream-map proc . argstreams)
(if (stream-null? (car argstreams))
the-empty-stream
(begin
(cons-stream (apply proc (map stream-car argstreams))
(apply stream-map
(cons proc (map stream-cdr argstreams)))))))