gens

Types

pub type Generator(a, s) {
  Generator(state: s, next: fn(s) -> option.Option(#(a, s)))
}

Constructors

pub opaque type LazyList(a)

Values

pub fn combine(
  g1: Generator(a, s1),
  g2: Generator(b, s2),
) -> Generator(#(a, b), #(s1, s2))

Combines two generators into one, advancing them separately

let two_powers =
  Generator(state: 1, next: fn(p) { Some(#(p, p * 2)) })
let bellow_three =
  Generator(state: 0, next: fn(n) { Some(#(n < 3, n + 1)) })

let z = combine(two_powers, bellow_three)
let #(res, _) = gen(z, 5)
echo res
// -> [#(1, True), #(2, True), #(4, True), #(8, False), #(16, False)]
pub fn drop(ga: LazyList(a), steps: Int) -> LazyList(a)

Drops the first n elements of a LazyList

new()                   // [0, 1, 2, 3, 4..]
|> drop(4)              // [4, 5, 6, 7..]
|> filter(int.is_even)  // [4, 6, 8..]
|> take(5)
// -> [4, 6, 8, 10, 12]
new()                   // [0, 1, 2, 3, 4..]
|> filter(int.is_even)  // [0, 2, 4, 6, 8..]
|> drop(4)              // [8, 10, 12..]
|> take(5)
// -> [8, 10, 12, 14, 16]
pub fn filter(ga: LazyList(a), f: fn(a) -> Bool) -> LazyList(a)

Filters elements from the takeerated list

new()
|> filter(fn(x) { x % 2 == 0 })
|> filter(fn(x) { x != 4 })
|> take(5)
// -> [0, 2, 6, 8, 10]
pub fn from_lazy_list(
  l: LazyList(a),
) -> Generator(a, LazyList(a))

Generates elements from the lazy list

let infinite_list = new() |> drop(3) |> map(fn(x) { x * 10 })
let ten_gen = from_lazy_list(infinite_list)
let #(res, _) = gen(ten_gen, 10)
echo res
// -> [30, 40, 50, 60, 70, 80, 90, 100, 110, 120]
pub fn from_list(l: List(a)) -> Generator(a, List(a))

Generates the lists elements

let gen_fruit = from_list(["apple", "banana", "orange"])
let #(fruit1, gen_fruit2) = get(gen_fruit)
echo fruit1
// -> Some("apple")
let #(fruit2, gen_fruit3) = get(gen_fruit2)
echo fruit2
// -> Some("banana")
let #(fruit3, gen_fruit4) = get(gen_fruit3)
echo fruit3
// -> Some("orange")
let #(fruit4, _) = get(gen_fruit4)
echo fruit4
// -> None
pub fn gen(
  g: Generator(a, s),
  n: Int,
) -> #(List(a), Generator(a, s))

Generates at most n elements and returns the updated gen

let counter =
  Generator(state: 0, next: fn(c) { Some(#(c, c + 1)) })
let #(nums, _) = gen(counter, 5)
echo nums // -> [0, 1, 2, 3, 4]
pub fn get(
  g: Generator(a, s),
) -> #(option.Option(a), Generator(a, s))

Returns the next element of a generator and the updated gen

let counter =
  Generator(state: 0, next: fn(c) { Some(#(c, c + 1)) })
case get(counter).0 {
  None -> Nil
  Some(x) -> echo x // -> 0
}
pub fn list_repeat(
  l: List(a),
) -> Generator(a, #(List(a), List(a)))

Generates the lists elements on repeat

let gen_fruit = list_repeat(["apple", "banana", "orange"])
let #(fruits, _) = gen(gen_fruit, 5)
echo fruits
// -> ["apple", "banana", "orange", "apple", "banana"]
pub fn list_zip(la: List(a), gb: LazyList(b)) -> List(#(a, b))

Zips a list with an infinite list

["a", "b", "c"] 
|> list_zip(new())
// -> [#("a", 0), #("b", 1), #("c", 2)]
pub fn map(ga: LazyList(a), f: fn(a) -> b) -> LazyList(b)

Maps each element of the takeerated list

new()
|> map(fn(x) { x + 3 })
|> map(int.to_string)
|> take(5)
// -> ["3", "4", "5", "6", "7"]
pub fn merge(
  g1: Generator(a, s1),
  g2: Generator(a, s2),
  comp: fn(a, a) -> order.Order,
) -> Generator(a, #(s1, s2))

Merges two sorted generators into one

let counter1 = Generator(0, fn(c) { Some(#(c, c + 1)) })
let counter2 = Generator(0, fn(c) { Some(#(c, c + 2)) })
let merged = merge(counter1, counter2, int.compare)
merged 
|> gen(8) 
|> echo
// -> #([0, 0, 1, 2, 2, 3, 4, 4], Generator(#(5, 6), fn() { ... }))
pub fn new() -> LazyList(Int)

Default LazyList for the list of natural numbers [0..]

new() |> take(5)
// -> [0, 1, 2, 3, 4]
pub fn take(ga: LazyList(a), n: Int) -> List(a)

Takes a finite number of elements from a LazyList

take(new(), 5)
// -> [0, 1, 2, 3, 4]
pub fn zip(ga: LazyList(a), gb: LazyList(b)) -> LazyList(#(a, b))

Zips two LazyLists into one

  • The resulting index is the maximum of the two takes
  • The filters get combined
  • For separate indexes, do list.zip(take(g1, n), take(g2, n))
let g1 = new() |> map(fn(x) { x + 2 })
let g2 = new() |> filter(int.is_even)
zip(g1, g2)
|> take(3)
// -> [#(2, 0), #(4, 2), #(6, 4)]
Search Document