tiinvo
Version:
A library of types and utilities for your TypeScript and JavaScript projects
358 lines (357 loc) • 8.47 kB
JavaScript
import * as Sequence from './Sequence.js';
const sortsymbol = Symbol('Sequence.sorted');
export function make(mod, ...args) {
const cmp = typeof mod === 'function' ? mod : mod.cmp;
const seq = Sequence.make.apply(null, args.sort(cmp));
seq[sortsymbol] = cmp;
return seq;
}
;
//#endregion
//#region guardables
/**
* Checks if the parameter `x` is a `SortedSequence.t<unknown>`
*
* @example
*
* ```ts
* import { SortedSequence, Str } from 'tiinvo'
*
* const s = SortedSequence.make(Str)
*
* SortedSequence.guard(s) // true
* SortedSequence.guard([]) // false
* ```
*
* @param x the value to guard
* @returns
* - `true` if x is a `SortedSequence.T<unknown>`
* - `false` otherwise
* @group Guards
* @since 4.0.0
*/
export const guard = (x) => Sequence.guard(x) && sortsymbol in x;
export function guardOf(g, x) {
const _g = (z) => {
return guard(z) && toArray(z).every(typeof g === 'function' ? g : g.guard);
};
return arguments.length === 2 ? _g(x) : _g;
}
;
export function cmp(a, b) {
if (guard(a) && guard(b)) {
return Sequence.cmp({ cmp: a[sortsymbol] }, a, b);
}
return (c) => Sequence.cmp({ cmp: a[sortsymbol] }, c, a);
}
export function eq(a, b) {
if (guard(a) && guard(b)) {
return Sequence.cmp({ cmp: a[sortsymbol] }, a, b) === 0;
}
return (b) => Sequence.cmp({ cmp: a[sortsymbol] }, a, b) === 0;
}
export function map(a, m) {
if (guard(a) && typeof m === 'function') {
return make.apply(null, [{ cmp: a[sortsymbol] }, ...[...a].map(m)]);
}
return (c) => {
return make.apply(null, [{ cmp: c[sortsymbol] }, ...[...c].map(a)]);
};
}
export function add(a, b) {
if (guard(a) && arguments.length === 2) {
return make.apply(null, [{ cmp: a[sortsymbol] }, ...a, b]);
}
return (c) => make.apply(null, [{ cmp: c[sortsymbol] }, ...c, a]);
}
export function concat(a, b) {
if (guard(a) && guard(b)) {
return make.apply(null, [{ cmp: a[sortsymbol] }, ...a, ...b]);
}
return (x) => make.apply(null, [{ cmp: x[sortsymbol] }, ...a, ...x]);
}
//#endregion
//#region accessors
/**
* Counts the number of elements that satisfy a given predicate
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s = SortedSequence.make(Num, 10, 20, 30)
*
* SortedSequence.count(s, Num.gt(10)) // 2
* SortedSequence.count(Num.gt(10))(s) // 2
* ```
*
* @template A the Sequence's element type
* @param a the sequence
* @param p the Filterable functor
* @returns the number of elements which satisfy the predicate `p`
* @group Accessors
* @since 4.0.0
*/
export const count = Sequence.count;
/**
* Gets an element at a specific index.
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s = SortedSequence.make(Num, 'hello', 'world')
*
* SortedSequence.get(s, 0) // 'hello'
* SortedSequence.get(s, 9) // null
* ```
*
* @template A the Sequence's element type
* @param a the sequence
* @param i the index of the element
* @returns
* - `Result.Ok<A>` if `i` is in bound
* - `Result.Err` if `i` is out of bound or negative
* @group Accessors
* @since 4.0.0
*/
export const get = Sequence.get;
/**
* Gets first element if any
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s0 = SortedSequence.make(Num, 10, 20, 30)
* const s1 = SortedSequence.make(Num)
*
* SortedSequence.first(s0) // 10
* SortedSequence.first(s1) // null
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the first element of the sequence:
* - `Option.Some<A>` if the sequence has at least one element
* - `Option.None` otherwise
* @group Accessors
* @since 4.0.0
*/
export const first = Sequence.first;
/**
* Gets last element if any.
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s0 = SortedSequence.make(Num, 10, 20, 30)
* const s1 = SortedSequence.make(Num)
*
* SortedSequence.last(s0) // 30
* SortedSequence.last(s1) // null
*
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns
* - `Option.Some<A>` if the sequence is not empty
* - `Option.None` otherwise
* @group Accessors
* @since 4.0.0
*/
export const last = Sequence.last;
/**
* Gets the length of a `SortedSequence.T<A>`
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s = SortedSequence.make(Num, 1, 2, 3)
*
* SortedSequence.length(s) // 3
* ```
*
* @since 4.0.0
*/
export const length = Sequence.length;
/**
* Gets values of a `SortedSequence.T<A>` as an immutable indexed object.
*
* @example
*
* ```ts
* import { SortedSequence, Str } from 'tiinvo'
*
* const s = SortedSequence.make(Str, 'hello', 'world')
*
* SortedSequence.values(s) // { 0: 'hello', 1: 'world' }
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the sequence values as an immutable dictionary
* @group Accessors
* @since 4.0.0
*/
export const values = Sequence.values;
//#endregion
//#region predicates
/**
* Returns `true` if the sorted list is empty.
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s = SortedSequence.make(Num)
* const s1 = SortedSequence.make(Num, 10)
*
* SortedSequence.empty(s) // true
* SortedSequence.empty(s1) // false
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns
* - 'true' if the sequence is empty
* - 'false' otherwise
* @group Predicates
* @since 4.0.0
*/
export const empty = Sequence.empty;
/**
* Returns `true` if the sorted list is populated.
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const s = SortedSequence.make(Num, 10, 20, 30)
*
* SortedSequence.populated(s) // true
* SortedSequence.populated(SortedSequence.make(Num)) // false
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns
* - 'true' if the sequence is populated
* - 'false' otherwise
* @group Predicates
* @since 4.0.0
*/
export const populated = Sequence.populated;
//#endregion
//#region serializables
/**
* Converts a `SortedSequence.T<A>` to an array of `a[]`
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const sl = SortedSequence.make(Num, 3, 2, 1)
*
* SortedSequence.toArray(sl) // [1, 2, 3]
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the output
* @group Serializables
* @since 4.0.0
*/
export const toArray = Sequence.toArray;
/**
* Converts a `SortedSequence.T<A>` to a jsonizable value
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const sl = SortedSequence.make(Num, 3, 2, 1)
*
* SortedSequence.toJSON(sl) // [1, 2, 3]
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the output
* @group Serializables
* @since 4.0.0
*/
export const toJSON = Sequence.toJSON;
/**
* Converts a `SortedSequence.T<A>` to a set of `Set<a>`
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const sl = SortedSequence.make(Num, 3, 2, 1)
*
* SortedSequence.toMap(sl) // Map([0, 1], [1, 2], [2, 3])
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the output
* @group Serializables
* @since 4.0.0
*/
export const toMap = Sequence.toMap;
/**
* Converts a `SortedSequence.T<A>` to a set of `Set<a>`
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const sl = SortedSequence.make(Num, 3, 2, 1)
*
* SortedSequence.toSet(sl) // Set(1, 2, 3)
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the output
* @group Serializables
* @since 4.0.0
*/
export const toSet = Sequence.toSet;
/**
* Converts a `SortedSequence.T<A>` to a string
*
* @example
*
* ```ts
* import { SortedSequence, Num } from 'tiinvo'
*
* const sl = SortedSequence.make(Num, 3, 2, 1)
*
* SortedSequence.toString(sl) // "1,2,3"
* ```
*
* @template A the Sequence's element type
* @param t the sequence
* @returns the output
* @group Serializables
* @since 4.0.0
*/
export const toString = Sequence.toString;
//#endregion