On this page:
Stream
Stream.expect_  of
Stream.first
Stream.rest
Stream.is_  empty
Stream.get
Stream.empty
Stream.empty
Stream.cons
Stream.cons
0.45+9.1.0.1

8.10 Streams🔗ℹ

A stream is a stateless sequence that supports Stream.first and Stream.rest operations. Accessing Stream.first multiple times for the same stream will produce the same result, and calling Stream.rest multiple times for the same stream will produce the same new stream that omits the first element. Lists, pair lists, and sequenceable ranges are streams, as well as lazy streams constructed using Stream.cons.

A stream is indexable using [] to access a stream element by position via #%index.

annotation

Stream

 

annotation

Stream.expect_of(ann, ...)

Matches any stream.

A Stream.expect_of(ann, ...) annotation is the same as Stream, but elements drawn from the stream via Stream.first have the static information of the anns (where multiple anns correspond to multiple values for each element, such as the key and value from a map). The extracted elements are not checked or converted, however, and each ann is used only for its static information.

Static information associated by Stream or Stream.expect_of makes an expression acceptable as a sequence to for in static mode.

property

property (stm :: Stream).first :: Any.like_element(stm)

 

property

property (stm :: Stream).rest

  :: Stream.expect_of(Any.like_element(stm))

 

method

method (stm :: Stream).is_empty :: Boolean

The Stream.first and Stream.rest properties report the first element of stm or a new stream that has the rest of the elements of stm, respectively.

The Stream.first and Stream.rest properties require non-empty streams. The Stream.is_empty method reports whether stm is empty.

> Stream.first([1, 2, 3])

1

> Stream.rest([1, 2, 3])

[2, 3]

> Stream.is_empty([1, 2, 3])

#false

> Stream.first([])

Stream.first: value does not satisfy annotation

  annotation: Stream && !satisfying(Stream.is_empty)

  value: []

> Stream.rest([])

Stream.rest: value does not satisfy annotation

  annotation: Stream && !satisfying(Stream.is_empty)

  value: []

method

method (stm :: Stream).get(n :: Nat) :: Any.like_element(stm)

Equivalent to stm[n] (with the default implicit #%index form). Returns the nth element of stm (starting from 0).

Returns or matches an empty stream. The emptry stream is not unique, so check for an empty stream by matching to Stream.empty or calling Stream.is_empty.

expression

Stream.cons(maybe_eager first_expr, maybe_eager rest_expr)

 

binding operator

Stream.cons(first_bind, rest_bind)

 

maybe_eager

 = 

~eager

 | 

ϵ

The Stream.cons expression form creates a stream whose first element is determined by evaluating first_expr on demand, and whose remainder is determined by evaluating rest_expr on demand. After first_expr or rest_expr is evaluated, its value is retained (and the corresponding expression is forgotten) for use by future demands. The result of rest_expr must satisfy Stream, but it is checked only at the point where the stream’s remainder is demanded. The result of first_expr can be multiple values, in which case the corresponding element of the stream consists of multiple values.

If first_expr ir rest_expr is prefixed with ~eager, then the expression is evaluated at the time the stream is constructed, instead of delaying until the result is demanded.

The Stream.cons binding form matches a non-empty stream, and it binds first_bind and rest_bind to the first and rest of the matched stream—but not demanding the first or rest if first_bind or rest_bind is literally _, respectively.

fun stream_skip(s :: Stream) :: Stream:

  match s

  | Stream.cons(fst, Stream.cons(_, rst)): Stream.cons(fst, stream_skip(rst))

  | Stream.cons(fst, _): Stream.cons(fst, Stream.empty)

  | Stream.empty: Stream.empty

def evens = stream_skip(0 ..)

> evens.first

0

> evens.rest.first

2

> evens[100]

200