rentgen
v0.1.2
Published
A ReasonML generator library, designed for Deno and Node
Downloads
1
Readme
Rentgen
A ReasonML generator library
Goals
- Uses an open api, which allows for the usage of fully in-reason generators, as well as external ones.
- Handling of sync and async generators.
- Written fully in Reason.
Documentation
Most of the documentation, together with examples, can be found inline
Sync
type next('a)
Represents the next value yielded by a generator
type gen('a)
Represents the api of a generator
next : gen('a) => next('a)
Increments the generator given, and returns its next) value.
return : (gen('a), 'a) => next('a)
Forces the generator to return the 2nd argument and stop.
throw : (gen('a), Js.Exn.t) => next('a)
Throws the error in the generator and forces it to stop.
from : 'a => gen('b)
Creates a generator from an external source, which implements the javascript generator api.
range : (~to_: int, ~from=0 : int, ~step=1 : int) => gen(int)
Creates a generator returning numbers from the range
<from; to_>
separated by the distance ofstep
. Creates an int range.
range(~to_=10)->foldl((+), 0)
// => 55
from_list : list('a) => gen('a)
Converts a list to a generator.
[1,2,3]->from_list->foldl((+), 0)
// => 6
inf : 'a => ('a => 'a) => gen('a)
Creates an infinite generator from an initial value and a successor function.
inf(0, a => a + 1) // => <0, 1, 2, 3, ...>
map : (gen('a), ('a => 'b)) => gen('b)
Transforms the values of a generator.
range(~to_=5, ()) -> map(a => a * 2)
// => <0, 2, 4, 6, 8, 10>
keep : (gen('a), ('a => bool)) => gen('a)
Returns only the values of the generator which match the function.
range(~to_=10, ()) -> keep(a => a mod 2 == 0)
// => <0, 2, 4, 6, 8, 10>
consume : (gen('a), 'a => 'b) => unit
Consumes a generator with a function.
// prints an infinite generator
inf(0, a => a + 1) -> consume(Js.Console.log)
// 0
// 1
// 2 ...
// => unit
foldl : (gen('a), (('b, 'a) => 'b), 'b) => 'b
Folds a generator into a single value.
[1,2,3]->from_list->foldl((+), 0)
// => 6
foldl1 : (gen('a), ('b, 'a) => 'b) => 'b
Folds a generator into a single value, taking the first value as the initial value.
range(~to_=3, ~from=1,())
->map(float_of_int)
->foldl1((a, b) => a /. b)
// => 1/6
take : (gen('a), int) => gen('a)
Takes n values of the generator or until it ends.
inf(0, a => a + 1) -> take(5)
// => <0, 1, 2, 3, 4>
take_while : (gen('a), ('a => bool)) => gen('a)
Takes the values of the generator as long as the function returns
true
.
inf(0, a => a*2 + 1)->take_while(a => a < 15)
// => <0, 1, 3, 7>
Async
type async('a) = Js.Promise.t('a)
type next_async('a) = async(next('a))
type gen_async('a)
next_async : gen_async('a) => next_async('a)
Returns the next value of an async generator
return_async : (gen_async('a), 'a) => next_async('a)
Returns the value given (as a promise), and forces the generator to stop
throw_async : (gen_async('a), Js.Exn.t) => next_async('a)
Throw the given error in the generator and forces it to stop
from_async : 'a => gen_async('b)
Creates a generator from an external source, which implements the async iterator api.
from_sync : gen('a) => gen_async('a)
Converts a sync generator into an async one.
inf(1, a => a + 1)
->from_sync
->take_async(100)
->consume_async(Js.Console.log)
map_async : (gen_async('a), ('a => 'b)) => gen_async('b)
Transforms an async generator using the function given.
puppy_stream
-> map_async(pet)
// => <async("doggo_1"), async("doggo_2"), ...>
foldl_async : (gen_async('a), (('b, 'a) => 'b), 'b) => async('b)
Folds an async generetor into a single promise
open_file("data/numbers.txt")
->map_async(Js.Float.fromString)
->foldl_async((+.), 0.)
// => async(21)
foldl1_async : (gen_async('a), (('b, 'a) => 'b)) => [async('b)]
Folds an async generator into a single promise, taking the first value as the initial value.
range(~to_=3, ~from=1, ())
->map(float_of_int)
->from_sync
->foldl1_async((a, b) => a /. b)
// => async(1/6)
consume_async : (gen_async('a), 'a => 'b) => async(unit)
Consumes an async stream, and returns an empty promise.
from_async(Deno.iter(file, ()))
->consume_async(Js.Console.log)
// (prints the file)
// => async(unit)
take_async : (gen_async('a), int) => gen_async('a)
Takes the first n elements from the async generator, and returns a new one of the length n.
infinite_puppies
->take_async(5)
// => async<"puppy1", "puppy2", ... , "puppy5">
take_while_async : (gen_async('a), ('a => bool)) => gen_async('a)
Takes elements of the generator as long as the condition given is met. Returns a new async generator.
keep_async : (gen_async('a), ('a => bool)) => gen_async('a)
Returns an async generator of the items which meet the condition given.
Examples
Fizz-buzz
open Sync;
let () = inf(0, a => a + 1)
->map(a =>
if (a mod 15 == 0) {
"fizzbuzz";
} else if (a mod 3 == 0) {
"fizz";
} else if (a mod 5 == 0) {
"buzz";
} else {
Js.Int.toString(a);
}
)
->consume(Js.Console.log);