gens/stream
================== Stream ==================
Types
Values
pub fn distinct(stream: Stream(a)) -> Stream(a)
Filters out duplicate elements of a Stream
map(naturals(), fn(x) { x / 3 })
|> take(10)
// -> [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]
map(naturals(), fn(x) { x / 3 })
|> distinct()
|> take(5)
// -> [0, 1, 2, 3, 4]
naturals()
|> map(fn(x) { [x, x + 3] })
|> flatten()
|> distinct()
|> take(10)
// -> [0, 3, 1, 4, 2, 5, 6, 7, 8, 9]
pub fn drop(stream: Stream(a), n: Int) -> Stream(a)
Drops the first n elements from the Stream
pub fn powers() -> Stream(Int) {
Stream(head: fn() { 1 }, tail: fn() { map(powers(), fn(x) { x * 2 }) })
}
powers() // 1, 2, 4, 8, 16..
|> drop(3)
|> take(5)
// -> [8, 16, 32, 64, 128]
pub fn filter(
stream: Stream(a),
pred: fn(a) -> Bool,
) -> Stream(a)
Filters elements from the Stream
pub fn naturals() -> Stream(Int) {
Stream(head: fn() { 0 }, tail: fn() { map(naturals(), fn(x) { x + 1 }) })
}
filter(naturals(), fn(x) { x % 3 == 0 })
|> take(5)
// -> [0, 3, 6, 9, 12]
pub fn flatten(stream: Stream(List(a))) -> Stream(a)
Flatten a Stream of Lists
let repeat_stream = naturals() |> map(fn(x) { list.repeat(x, x) })
repeat_stream
|> take(5)
// -> [[], [1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
repeat_stream
|> flatten()
|> take(10)
// -> [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
pub fn fold(stream: Stream(a), f: fn(a, fn() -> b) -> b) -> b
Folds the Stream into a single value using an accumulator
let stream_or = fn(s: Stream(Bool)) -> Bool {
fold(s, fn(x, next) { x || next() })
}
// If at least one element is True, then the fold ends
// If all elements in the Stream are False, the fold runs infinitely
stream_or(naturals() |> map(fn(x) { x == 10 }))
// -> True
pub fn from_lazy_list(lz: lazy.LazyList(a)) -> Stream(a)
Conversion from LazyList to Stream
let lazy_odds =
lazy.new()
|> lazy.filter(int.is_odd)
|> lazy.map(int.to_string)
let stream_odds = from_lazy_list(lazy_odds)
stream_odds
|> take(5)
// -> ["1", "3", "5", "7", "9"]
pub fn list_zip(
list: List(a),
stream: Stream(b),
) -> List(#(a, b))
Zips a list with a Stream
list_zip(["a", "b", "c"], naturals())
// -> [#("a", 0), #("b", 1), #("c", 2)]
pub fn map(stream: Stream(a), f: fn(a) -> b) -> Stream(b)
Maps each element of the Stream
pub fn alt(positive: Bool) -> Stream(Int) {
Stream(
head: fn() {
case positive {
True -> 1
False -> -1
}
},
tail: fn() { alt(!positive) },
)
}
alt(True)
|> map(fn(x) { x * 2 })
|> map(fn(x) { int.to_string(x) <> " oranges" })
|> take(5)
// -> ["2 oranges", "-2 oranges", "2 oranges", "-2 oranges", "2 oranges"]
pub fn merge(
stream1: Stream(a),
stream2: Stream(a),
compare: fn(a, a) -> order.Order,
) -> Stream(a)
Merges two sorted Streams
merge(naturals(), naturals() |> map(fn(x) { x * 2 }), int.compare)
|> take(8)
// -> [0, 0, 1, 2, 2, 3, 4, 4]
pub fn scan(
stream: Stream(a),
acc: b,
f: fn(a, b) -> b,
) -> Stream(b)
Scans the Stream and reconstructs it using an accumulator
pub fn dummy() -> Stream(Nil) {
Stream(head: fn() { Nil }, tail: dummy)
}
let evens: Stream(Int) = scan(dummy(), 0, fn(_, acc) { acc + 2 })
evens
|> take(5)
// -> [0, 2, 4, 6, 8]
pub fn take(stream: Stream(a), n: Int) -> List(a)
Takes a finite number of elements from the Stream
pub fn ones() -> Stream(Int) {
Stream(head: fn() { 1 }, tail: ones)
}
ones()
|> take(5)
// -> [1, 1, 1, 1, 1]
pub fn to_lazy_list(s: Stream(a)) -> lazy.LazyList(a)
Conversion from Stream to LazyList
let stream_evens =
naturals()
|> filter(int.is_even)
|> map(int.to_string)
let lazy_evens = to_lazy_list(stream_evens)
lazy_evens
|> lazy.take(5)
// -> ["0", "2", "4", "6", "8"]
pub fn while(
stream: Stream(a),
condition: fn(a) -> Bool,
) -> List(a)
Takes elements from the Stream until the condition is false
naturals()
|> while(fn(x) { x < 5 })
// -> [0, 1, 2, 3, 4]