Lazy sequences for ReScript.
npm install @jmagaram/rescript-seqA _sequence_ is a list whose elements are computed only on demand, similar to JavaScript iterables. Sequences are produced and transformed lazily (one element at a time) rather than eagerly (all at once). This allows constructing conceptually infinite sequences. When your data is an array, call fromArray to create a sequence, which is just a lightweight function that iterates over its values. And then you can use the sequence functions to analyze and transform it with far more flexibility and power than what is possible with the built-in array functions. Sequences can sometimes provide better performance than an array when not all elements are used.
Sequences are in the standard libraries of F#, OCaml, Rust, .net, Haskell, and Python. There are JavaScript libraries to consume iterables, and a Stage 3 TC39 proposal to add iterator helpers.
This is a full-featured package to create and consume sequences in ReScript. Highlights:
- Enables more elegant and concise solutions than using imperative code and arrays
- 100+ functions, chosen by researching the best from other libraries
- API documentation
- Comprehensive test suite
- Written 100% in ReScript; look at the code and tests to see how it works.
- Create sequences with fromArray, range, unfold, cycle, permutations, replicate, ...
- Transform with map, filter, split, takeUntil, scan, tap, pairwise...
- Combine with zip, map3, allPairs, sortedMerge, interleave...
- Calculate with reduceUntil, maxBy, every, findMap, isSortedBy, toArray...
See code examples.
``sh`
npm install @jmagaram/rescript-seq
Add to your rescript.json...
`diff`
{
...
+ "bs-dependencies": ["@jmagaram/rescript-seq"]
}
All functions are in the Seq module. See other examples.
`rescript`
["a", "b", "c", "d"]
->Seq.fromArray
->Seq.combinations(3)
->Seq.map(((_, combo)) => combo->Seq.join(""))
->Seq.join(", ")
->Console.log // a, b, ba, c, ca, cb, cba, d, da, db, dba, dc, dca, dcb
`rescript
type t<'a> // A lazy sequence of 'a
// Construct
let combinations: (t<'a>, int) => t<(int, t<'a>)>
let cons: ('a, t<'a>) => t<'a>
let cycle: t<'a> => t<'a>
let delay: (unit => t<'a>) => t<'a>
let empty: t<'a>
let unfoldMany: ('a, 'a => t<('b, 'a)>) => t
let forever: 'a => t<'a>
let foreverWith: (unit => 'a) => t<'a>
let fromArray: (~start: int=?, ~end: int=?, array<'a>) => t<'a>
let fromList: list<'a> => t<'a>
let init: (int, int => 'a) => t<'a>
let iterate: ('a, 'a => 'a) => t<'a>
let iterateWhile: ('a, 'a => option<'a>) => t<'a>
let once: 'a => t<'a>
let onceWith: (unit => 'a) => t<'a>
let permutations: (t<'a>, int) => t<(int, t<'a>)>
let range: (int, int) => t
let rangeMap: (int, int, int => 'a) => t<'a>
let replicate: ('a, int) => t<'a>
let replicateWith: (unit => 'a, int) => t<'a>
let unfold: ('a, 'a => option<('b, 'a)>) => t<'b>
// Transform
let cache: t<'a> => t<'a>
let chunkBySize: (t<'a>, int) => t
let drop: (t<'a>, int) => t<'a>
let dropLast: (t<'a>, int) => t<'a>
let dropUntil: (t<'a>, 'a => bool) => t<'a>
let dropWhile: (t<'a>, 'a => bool) => t<'a>
let filter: (t<'a>, 'a => bool) => t<'a>
let filteri: (t<'a>, ('a, int) => bool) => t<'a>
let filterMap: (t<'a>, 'a => option<'b>) => t<'b>
let filterMapi: (t<'a>, ('a, int) => option<'b>) => t<'b>
let filterOk: t
let filterSome: t
// Combine
let allPairs: (t<'a>, t<'b>) => t<('a, 'b)>
let append: (t<'a>, t<'a>) => t<'a>
let concat: (t<'a>, t<'a>) => t<'a>
let interleave: (t<'a>, t<'a>) => t<'a>
let map2: (t<'a>, t<'b>, ('a, 'b) => 'c) => t<'c>
let map3: (t<'a>, t<'b>, t<'c>, ('a, 'b, 'c) => 'd) => t<'d>
let map4: (t<'a>, t<'b>, t<'c>, t<'d>, ('a, 'b, 'c, 'd) => 'e) => t<'e>
let map5: (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, ('a, 'b, 'c, 'd, 'e) => 'f) => t<'f>
let orElse: (t<'a>, t<'a>) => t<'a>
let prepend: (t<'a>, t<'a>) => t<'a>
let sortedMerge: (t<'a>, t<'a>, ('a, 'a) => float) => t<'a>
let zip: (t<'a>, t<'b>) => t<('a, 'b)>
let zip3: (t<'a>, t<'b>, t<'c>) => t<('a, 'b, 'c)>
let zip4: (t<'a>, t<'b>, t<'c>, t<'d>) => t<('a, 'b, 'c, 'd)>
let zip5: (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>) => t<('a, 'b, 'c, 'd, 'e)>
// Reduce, consume, and calculate
let at: (t<'a>, int) => option<'a>
let compare: (t<'a>, t<'b>, ('a, 'b) => int) => int
let consume: t<'a> => unit
let equals: (t<'a>, t<'b>, ('a, 'b) => bool) => bool
let every: (t<'a>, 'a => bool) => bool
let everyOk: t
let everySome: t