For Gauche 0.9.9


Next: , Previous: , Up: ライブラリモジュール - ユーティリティ   [Contents][Index]

12.71 util.stream - ストリームライブラリ

Module: util.stream

このモジュールは遅延ストリームのライブラリを提供します。このモジュール にはsrfi-40とsrfi-41で定義されている関数および構文が含まれています。 後者は(scheme stream)としてR7RS largeの一部になっています。


Next: , Previous: , Up: ストリームライブラリ   [Contents][Index]

12.71.1 Stream primitives

Function: stream? obj

[R7RS stream] {util.stream} objutil.streamの手続きによって作成されたストリームであ る場合にかぎり#tを返します。

Variable: stream-null

[R7RS stream] {util.stream} NULLストリームのシングルトンインスタンス。

Macro: stream-cons object stream

[R7RS stream] {util.stream} ストリームの基本構成子。objectstreamの先頭に追加し、新し いストリームを返します。

Function: stream-null? obj

[R7RS stream] {util.stream} objがNULLストリームの場合にのみ#tを返します。

Function: stream-pair? obj

[R7RS stream] {util.stream} objがNULLストリームではないストリームのときにのみ#tを返します。

Function: stream-car s

[R7RS stream] {util.stream} ストリームsの最初の要素を返します。

Function: stream-cdr s

[R7RS stream] {util.stream} ストリームsの最初の要素をのぞいたのこりの要素をストリームとして 返します。

Macro: stream-delay expr

[SRFI-40] {util.stream} exprの遅延形式であるストリームを返します。

原則として、ストリームを生成する関数はすべからく結果を stream-delayでラップすべきです。 (以下に述べるstream-lambda, stream-let, stream-defineを 使う手もあります)。

Macro: stream-lambda formals body body2 …

[R7RS stream] {util.stream} ストリームを返す関数を作る簡易マクロです。 (stream-lambda formals body body2 …)(lambda formals (stream-delay body body2 …))と同じです。


Next: , Previous: , Up: ストリームライブラリ   [Contents][Index]

12.71.2 Stream constructors

Function: stream obj …

[SRFI-40] {util.stream} 要素がobj …であるような新しいストリームを返します。

註:これはsrfi-41 (scheme.stream)のstreamとは異なります。 srfi-41の方はマクロで、引数の評価が遅延されます。srfi-41版はこのモジュールでは stream+と言う名前で提供されます。

(stream 1 2 3))     ⇒ a stream that contains (1 2 3)
(stream 1 (/ 1 0))) ⇒ error
Macro: stream+ expr …

{util.stream} 要素がexpr …の結果であるような新たなストリームを作って返します。

これはsrfi-41(scheme.stream)のstreamと同じです。 各exprはアクセスされるまで評価されません。

(define s (stream+ 1 (/ 1 0)))  ;; doesn't yield an error

(stream-car s)  ⇒ 1

(stream-cadr s) ⇒ error
Function: stream-unfold f p g seed

[R7RS stream] {util.stream} 次の手順で生成される要素をもつ新たなストリームを作成して返します。

註:残念なことに、この手続きは他の *-unfold 系手続きと異なる順序で 引数を取ります。他の手続きはp f g (述語、値生成、シード生成) の順です。 さらに、他の手続きでは述語は停止する時に真を返します。

(stream->list
 (stream-unfold integer->char (cut < <> 58) (cut + 1 <>) 48))
 ⇒ (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)
Function: stream-unfoldn f seed n

[SRFI-40] {util.stream} 互いに関連する n 本のストリームを生成します。それぞれの内容は fおよびseedを使って生成します。

fは現在のシード値とともに呼ばれ、n+1個の値 を返します。

(f seed)
  => seed result_0 result_1 … result_n-1

最初の値は次のシード値になります。Result_kは以下の形式のどれかで なければなりません。

(val)

valk-番目のストリームの次のcar部になります。

#f

k-番目のストリームの新しい情報はありません。

()

k-番目のストリームの最後に到達しました。

以下の例では2つのストリームが作られます。最初のものは奇数の無限ストリー ムで、2つめのものは偶数の無限ストリームです。

gosh> (define-values (s0 s1)
        (stream-unfoldn (lambda (i)
                          (values (+ i 2)          ;; next seed
                                  (list i)         ;; for the first stream
                                  (list (+ i 1)))) ;; for the second stream
                        0 2))
#<undef>
gosh> (stream->list (stream-take s0 10))
(0 2 4 6 8 10 12 14 16 18)
gosh> (stream->list (stream-take s1 10))
(1 3 5 7 9 11 13 15 17 19)
Function: stream-unfolds f seed

[R7RS stream] {util.stream} stream-unfoldnと似ていますが、結果のストリームの数は fの戻り値の数により決定されます。詳しくは 上のstream-unfoldnの説明を参照してください。

Function: stream-constant obj …

[R7RS stream] {util.stream} obj …を繰り返す無限ストリームを返します。

(stream->list 10 (stream-constant 1 2))
  ⇒ (1 2 1 2 1 2 1 2 1 2)
Function: make-stream n :optional init

{util.stream} n個のinitを要素とする新しいストリームを生成します。 initが省略された場合#fが使われます。nを負の値にする と無限ストリームが生成されます。

Function: stream-tabulate n init-proc

{util.stream} n個の要素をもつ新しいストリームを生成します。k-番目の要素 は init-prock に適用して得られます。nを負の値にする と無限ストリームが生成されます。

Function: stream-iota :optional count start step

{util.stream} startからはじまり、stepずつ要素が増加する数値のストリーム を生成します。ストリームの長さは非負の実数countを越えない最大の整数値です。 count, start, stepのデフォルト値はそれぞれ +inf.0, 0 および 1です。

startstepが正確数で、countが正確数か無限大の場合、 正確数のストリームが作られます。そうでなければ非正確数のストリームになります。

Function: stream-range start :optional end step

[R7RS stream] {util.stream} startから始まりstepおきにendの手前まで続く実数のストリームを 作って返します。endが省略された場合は正の無限大が使われます。 stepが省略された場合、startendより小さければ1が、 大きければ-1が使われます。

startstepが正確数で、endが正確数か無限大の場合は、 正確数のシーケンスが、そうでない場合は非正確数のシーケンスが生成されます。

R7RSのscheme.streamでは、end引数は必須です。

(stream->list (stream-range 0 10))
 ⇒ (0 1 2 3 4 5 6 7 8 9)
Function: stream-from start :optional step

[R7RS stream] {util.stream} もうひとつの数値シーケンス生成手続きです。i番目の項が (+ start (* i step))であるような無限シーケンスを返します。 stepが省略されたら1が使われます。 startstepが正確数なら、正確数のシーケンスが、 そうでなければ非正確数のシーケンスが返されます。

Function: stream-iterate f seed

[R7RS stream] {util.stream}

(stream->list 5 (stream-iterate (cut cons 'x <>) '()))
  ⇒ (() (x) (x x) (x x x) (x x x x))
Function: stream-xcons a b

{util.stream} (stream-cons b a)のこと。利便性のためだけにある。

Function: stream-cons* elt … stream

{util.stream} streamの前にelt …を連結した新しいストリームを生成し ます。

Function: list->stream list

[R7RS stream] {util.stream} listの要素を要素とする新たなストリームを作って返します。

Function: string->stream string :optional tail-stream

{util.stream} 文字列を文字のストリームに変換します。tail-streamが与えられた場合は、 文字ストリームの後にそれが付け加えられます。

(stream->list (string->stream "abc" (list->stream ’(1 2 3)))) ⇒ (#\a #\b #\c 1 2 3)

Function: stream-format fmt arg …

{util.stream} string->stream(format fmt arg …)に適用した結果の ストリームを返します。

Function: port->stream :optional iport reader closer

[R7RS stream] {util.stream} iportからreaderを使って読み出されるデータを要素とする新たなストリームを 作って返します。iportのデフォルトは現在の入力ポート、 readerのデフォルトはread-charです。

readerがEOFを返したらストリームの終端となります (EOF自体は ストリームには含まれません)。 EOFに達してもポートはクローズされません。

もしcloser引数が与えられたら、それがiportを引数として EOFが読まれた直後に呼ばれます。そこでポートをクローズするこはできます。

readercloser引数はR7RSのscheme.streamでは 定義されない、Gaucheの拡張です。

Function: iterator->stream iter

{util.stream} A generic procedure to turn an internal iterator iter into a stream of iterated results.

The iter argument is a procedure that takes two arguments, next and end, where next is a procedure that takes one argument and end is a thunk. Iter is supposed to iterate over some set and call next for each argument, then call end to indicate the end of the iteration. Here’s a contrived example:

(stream->list
 (iterator->stream
  (lambda (next end) (for-each next '(1 2 3 4 5)) (end))))
 ⇒ (1 2 3 4 5)

Internally iterator->stream uses the “inversion of iterator” technique, so that iter only iterates to the element that are needed by the stream. Thus iter can iterate over an infinite set. In the following example, iter is an infinite loop calling next with increasing integers, but only the first 10 elements are calculated because of stream-take:

(stream->list
 (stream-take
  (iterator->stream
   (lambda (next end)
     (let loop ((n 0)) (next n) (loop (+ n 1)))))
  10))
 ⇒ (0 1 2 3 4 5 6 7 8 9)
Macro: stream-of elt-expr clause …

[R7RS stream] {util.stream} ストリーム内包表記。各要素がelt-exprで計算されるストリームを返します。 clauseelt-exprのスコープを作り、繰り返しを制御します。 各clauseは以下の形のいずれかです:

(x in stream-expr)

stream-exprが返すストリームの各要素を、xに束縛して繰り返します。 変数xのスコープは後続のclauseおよびelt-exprです。

(x is expr)

変数xに値exprの結果を束縛します。xのスコープは 後続のclauseおよびelt-exprです。

expr

expr#fに評価されたらこの回は値を生成せずに打ちきられ、 次の繰り返しに進みます。

次の内包表記はピタゴラス数の無限シーケンスを生成します:

(define pythagorean-triples
  (stream-of (list a b c)
    (c in (stream-from 3))
    (b in (stream-range 2 c))
    (a in (stream-range 1 b))
    (= (square c) (+ (square b) (square a)))))

(stream->list 5 pythagorean-triples)
  ⇒ ((3 4 5) (6 8 10) (5 12 13) (9 12 15) (8 15 17))

Next: , Previous: , Up: ストリームライブラリ   [Contents][Index]

12.71.3 Stream binding

Macro: define-stream (name . formals) body body2 …

[R7RS stream] {util.stream} ストリームを作って返す関数を手軽に定義するマクロです。 次のフォームと同じです:

(define (name . formals)
  (stream-delay
    (let () body body2 …)))
Macro: stream-let loop-var ((var init) …) body body2 …

[R7RS stream] {util.stream} lazyなnamed-letによるループを書くときに便利なマクロです。次のフォームと同じです:

(let loop-var ((var init) …)
  (stream-delay
    (let () body body2 …)))
Macro: stream-match stream-expr clause …

[R7RS stream] {util.stream} このマクロは簡単なパターンマッチングを使ってストリームの要素にアクセスします。 stream-exprはストリームを返す式でなければなりません。 各clause(pattern expr)(pattern fender expr)という形です。

入力ストリームは各patternに順マッチするかどうかテストされます。 patternには以下の形のいずれかです:

()

空のストリームとマッチします。

(p0 p1 …)

パターン内の要素の数と入力ストリームの要素数が一致した時にマッチします。

(p0 p1 … . pRest)

入力ストリームの要素数が、pRestを除いたパターン内の要素の数以上であれば マッチします。pRestにはストリームの残りがマッチします。

pRest

入力ストリーム全体とマッチします。

パターンの各要素は識別子かリテラルのアンダースコア_です。 アンダースコア以外の識別子の場合は、それらが対応する入力ストリームの要素に 束縛された環境でfenderexprが評価されます。

もしfenderがあれば、まずそれが評価され、#fであったらそのclauseの マッチは失敗となり、次のclauseが試されます。

そうでなければexprが評価され、その結果がstream-matchの結果となります。

入力ストリームの要素はマッチに必要なだけ取り出されます。

次の例は、ストリーム中の真の値の数を数えています:

(define (num-trues strm)
  (stream-match strm
    (() 0)
    ((head . tail) head (+ 1 (num-trues tail)))
    ((_ . tail) (num-trues tail))))

(num-trues (stream #f #f #t #f #t #f #t #t))
  ⇒ 4

Next: , Previous: , Up: ストリームライブラリ   [Contents][Index]

12.71.4 Stream consumers

これらの手続きはストリームを取り、その要素を消費し尽します。

Function: stream-for-each func . streams

[R7RS stream] {util.stream} funcstreamsの各要素に適用します。 streamsが終端に達したところで停止します。

Function: stream-fold f seed stream

[R7RS stream] {util.stream} fを現在のシード値とstreamの要素に適用し、その結果を次のシード値として streamが終端に達するまで繰り返します。最初のシード値はseed引数で与えられます。 最後のシード値が返されます。

註: fの引数順は、他の*-fold系関数のそれと異なることに注意してください。 例えばfold (リストをたどる手続き参照) では最初に要素、次にシード値が 渡されます。

(stream-fold - 0 (stream 1 2 3 4 5))
  ⇒ -15

Previous: , Up: ストリームライブラリ   [Contents][Index]

12.71.5 Stream operations

Function: stream-append stream …

[R7RS stream] {util.stream} 与えられたstreamを全部つないだ新たなストリームを返します。

Function: stream-concat streams
Function: stream-concatenate streams

[R7RS stream] {util.stream} R7RS scheme.streamstream-concatを定義しました。 Gaucheにはstream-concatenateがあったので互換性のためにそちらも残しています。 どちらも同じです。

streamsはストリームのストリームです。各ストリームを連結したストリームを作って 返します。stream-appendと違い、streamsは無限個のストリームを生成 することができます。

Function: stream-map func stream stream2 …

[R7RS stream] {util.stream} streamsの各要素にfuncを適用した値を要素とする新しいストリー ムを返します。

Function: stream-scan func seed stream

[R7RS stream] {util.stream} seed(func seed e0)(func (func seed e0) e1) … で構成されるストリームを返します。ここで e0e1 …は入力ストリームstreamの要素です。 streamが有限なら、その要素よりひとつ多い要素が出力ストリームには含まれます。

(stream->list
  (stream-scan xcons '() (stream 1 2 3 4 5)))
 ⇒ (() (1) (2 1) (3 2 1) (4 3 2 1) (5 4 3 2 1))
Function: stream-zip stream …

[R7RS stream] {util.stream} 入力ストリームの対応する要素のリストを要素とするストリームを作って返します。 入力ストリームのいずれかが終端に達した時に出力ストリームも終わります。

(stream->list
 (stream-zip (stream 1 2 3) (stream 'a 'b 'c 'd)))
 ⇒ ((1 a) (2 b) (3 c))
Function: stream-filter pred stream

[R7RS stream] {util.stream} predをパスする要素のみからなる新しいストリームを返します。

Function: stream-remove pred stream

{util.stream} 述語predを満たさない要素のみからなる新しいストリームを返します。

Function: stream-partition pred stream

{util.stream} 二つのストリームを返します。最初のストリームはstreamの要素のうち 述語predを満たすもの、次のストリームはpredを満たさないもので構成されます。

Function: stream->list stream
Function: stream->list n stream

[R7RS stream] {util.stream} Converts a stream to a list. In the first form, all elements from stream are taken (thus it never returns if stream is infinite). In the second form, at most n elements are taken, where n must be a nonnegative exact integer.

Note: In usual Scheme conventions, the optional n comes after the main argument (stream).

Function: stream->string stream

{util.stream} Converts a stream to a list. All elements of stream must be characters, or an error is signaled.

Function: stream-lines stream

{util.stream} Splits stream where its element equals to #\n, and returns a stream of splitted streams.

(stream->list
 (stream-map stream->string
             (stream-lines (string->stream "abc\ndef\nghi"))))
 ⇒ ("abc" "def" "ghi")
Function: stream= elt= stream …

{util.stream} Returns true iff each corresponding element of stream … are the same in terms of elt=. This procedure won’t terminate if any of streams is infinite.

Function: stream-prefix= stream prefix :optional elt=

{util.stream} Compares initial elements of stream against a list prefix by elt=. Only as many elements of stream as prefix has are checked.

Function: stream-caar s
Function: stream-cadr s

Function: stream-cdddar s
Function: stream-cddddr s

{util.stream} (stream-caar s) = (stream-car (stream-car s)) etc.

Function: stream-ref stream pos

[R7RS stream] {util.stream} ストリームのpos番目の要素を返します。posは非負の正確な整数でなければなりません。

Function: stream-first s
Function: stream-second s
Function: stream-third s
Function: stream-fourth s
Function: stream-fifth s
Function: stream-sixth s
Function: stream-seventh s
Function: stream-eighth s
Function: stream-ninth s
Function: stream-tenth s

{util.stream} (stream-first s) = (stream-ref s 0) etc.

Function: stream-take stream count
Function: stream-take-safe stream count

{util.stream} Returns a new stream that consists of the first count elements of the given stream. If the given stream has less than count elements, the stream returned by stream-take would raise an error when the elements beyond the original stream is accessed. On the other hand, the stream returned by stream-take-safe will return a shortened stream when the given stream has less than count elements.

(stream->list (stream-take (stream-iota -1) 10))
 ⇒ (0 1 2 3 4 5 6 7 8 9)

(stream-take (stream 1 2) 5)
 ⇒ stream

(stream->list (stream-take (stream 1 2) 5))
 ⇒ error

(stream->list (stream-take-safe (stream 1 2) 5))
 ⇒ (1 2)

Note: srfi-41 (scheme.stream) also defines stream-take, but the argument order is reversed, and also it allows stream to have less than count elements.

Function: stream-drop stream count
Function: stream-drop-safe stream count

{util.stream} Returns a new stream that consists of the elements in the given stream except the first count elements. If the given stream has less than count elements, stream-drop returns a stream that raises an error if its element is accessed, and stream-drop-safe returns an empty stream.

Note: srfi-41 (scheme.stream) also defines stream-drop, but the argument order is reversed, and also it allows stream to have less than count elements.

Function: stream-intersperse stream element

{util.stream} Returns a new stream in which element is inserted between elements of stream.

Function: stream-split stream pred

{util.stream}

Function: stream-last stream

{util.stream}

Function: stream-last-n stream count

{util.stream}

Function: stream-butlast stream

{util.stream}

Function: stream-butlast-n stream count

{util.stream}

Function: stream-length stream

[R7RS stream] {util.stream} Returns the number of elements in stream. It diverges if stream is infinite.

Function: stream-length>= stream n
Function: stream-length= stream n

{util.stream}

Function: stream-reverse stream :optional tail-stream

[R7RS stream] {util.stream} streamの要素を逆順にしたストリームを返します。tail-streamが与えられた 場合、逆順にしたストリームの後にそれ付け加えられます。

省略可能なtail-streamはGaucheの拡張です。詳しくは reverseの説明を参照してください (他のリスト手続き)。

Function: stream-count pred stream …

{util.stream}

Function: stream-find pred stream

{util.stream}

Function: stream-find-tail pred stream

{util.stream}

Function: stream-take-while pred stream

[R7RS stream] {util.stream}

Function: stream-drop-while pred stream

[R7RS stream] {util.stream}

Function: stream-span pred stream

{util.stream}

Function: stream-break pred stream

{util.stream}

Function: stream-any pred stream …

{util.stream}

Function: stream-every pred stream …

{util.stream}

Function: stream-index pred stream …

{util.stream}

Function: stream-member obj stream :optional elt=
Function: stream-memq obj stream
Function: stream-memv obj stream

{util.stream}

Function: stream-delete obj stream :optional elt=

{util.stream}

Function: stream-delete-duplicates stream :optional elt=

{util.stream}

Function: stream-grep re stream

{util.stream}

Function: write-stream stream :optional oport writer

{util.stream}


Previous: , Up: ストリームライブラリ   [Contents][Index]