@fink/std-lib
Version:
fink standard lib
750 lines (627 loc) • 18.6 kB
JavaScript
import { _in_ } from "@fink/js-interop/runtime.js";
// TODO: should all js-interop imports be virtual imports from e.g. @fink/runtime/*
// and have the compiler translate it to the appropriate runtime module
import { _iterable_, _iter_, _next_, _is_done_, _is_empty_, _empty_iter_ } from "@fink/js-interop/runtime.js";
import { _len_, _join_, _reverse_, _sort_, _zip_ } from "@fink/js-interop/runtime.js";
import { max_int } from "./num.js";
import { is_fn } from "./fn.js";
export const iter = _iter_;
export const next = _next_;
export const is_empty = _is_empty_;
export const length = _len_;
export const zip = _zip_;
export const reverse = _reverse_;
export const join = _join_;
export const sort = _sort_;
export const with_ctx = initial_ctx => {
const next_fn = (iterable, ctx = initial_ctx) => _next_(iterable, ctx);
return items => _iterable_(next_fn, _iter_(items));
};
export const fold = (initial, fold_fn) => {
const foldr = (..._args) => {
while (true) {
const [iterable, prev, ctx, fold_fn] = _args;
const [item, rest, next_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_1 = rest;
if (_is_done_(ˆvalue_1)) {
return prev;
}
{
{
const result = fold_fn(item, prev, undefined, next_ctx);
_args = [rest, result, next_ctx, fold_fn];
continue;
}
}
}
}
};
return items => {
const it = _iter_(items);
{
const ˆvalue_3 = true;
if (ˆvalue_3 === is_fn(fold_fn)) {
return foldr(it, initial, undefined, fold_fn);
}
{
return foldr(it, undefined, undefined, initial);
}
}
};
};
export const fold_ac = (initial, ctx, fold_fn) => {
const foldr = (..._args2) => {
while (true) {
const [iterable, prev, acc, ctx, fold_fn] = _args2;
const [item, rest, f_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_5 = rest;
if (_is_done_(ˆvalue_5)) {
return [prev, f_ctx];
}
{
{
const [result, next_acc, next_ctx = f_ctx] = fold_fn(item, prev, acc, f_ctx);
_args2 = [rest, result, next_acc, next_ctx, fold_fn];
continue;
}
}
}
}
};
return items => {
const it = _iter_(items);
const uses_ctx = is_fn(fold_fn);
let _do_result;
ˆmatch_8: {
const ˆvalue_7 = true;
if (ˆvalue_7 === is_fn(fold_fn)) {
_do_result = [, ctx, fold_fn];
break ˆmatch_8;
}
{
_do_result = [,, ctx];
break ˆmatch_8;
}
}
const acc_ctx_fold_fn = _do_result;
_do_result = undefined;
const [result, next_ctx] = foldr(it, initial, ...acc_ctx_fold_fn);
{
const ˆvalue_9 = true;
if (ˆvalue_9 === uses_ctx) {
return [result, next_ctx];
}
{
return result;
}
}
};
};
export const unfold = next_item_fn => {
const next_fn = (prev, ctx) => {
const item = next_item_fn(prev, undefined, ctx);
const next_iter = _iterable_(next_fn, item);
return [item, next_iter, ctx];
};
return start => _iterable_(next_fn, start);
};
export const unfold_ac = next_item_fn => {
const next_fn = ([prev, acc], ctx) => {
const [item, next_acc, next_ctx = ctx] = next_item_fn(prev, acc, ctx);
const next_iter = _iterable_(next_fn, [item, next_acc]);
return [item, next_iter, next_ctx];
};
return start => _iterable_(next_fn, [start]);
};
export const filter = filter_fn => {
const next_fn = (..._args3) => {
while (true) {
const [iterable, ctx] = _args3;
const [item, rest, next_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_11 = rest;
if (_is_done_(ˆvalue_11)) {
return [item, rest, next_ctx];
}
{
{
const keep = filter_fn(item, undefined, next_ctx);
{
const ˆvalue_13 = keep;
if (ˆvalue_13 === true) {
{
const next_iter = _iterable_(next_fn, rest);
return [item, next_iter, next_ctx];
}
}
{
_args3 = [rest, next_ctx];
continue;
}
}
}
}
}
}
};
return items => _iterable_(next_fn, _iter_(items));
};
export const filter_ac = filter_fn => {
const next_fn = (..._args4) => {
while (true) {
const [[iterable, acc], ctx] = _args4;
const [item, rest, f_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_15 = rest;
if (_is_done_(ˆvalue_15)) {
return [item, rest, f_ctx];
}
{
{
const [keep, next_acc, next_ctx = f_ctx] = filter_fn(item, acc, f_ctx);
{
const ˆvalue_17 = keep;
if (ˆvalue_17 === true) {
{
const next_iter = _iterable_(next_fn, [rest, next_acc]);
return [item, next_iter, next_ctx];
}
}
{
_args4 = [[rest, next_acc], next_ctx];
continue;
}
}
}
}
}
}
};
return items => _iterable_(next_fn, [_iter_(items)]);
};
export const ˆwhile = while_fn => {
const next_fn = (iterable, ctx) => {
const [item, rest, next_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_19 = rest;
if (_is_done_(ˆvalue_19)) {
return [item, rest, next_ctx];
}
{
{
const ˆcontinue = while_fn(item, undefined, next_ctx);
{
const ˆvalue_21 = ˆcontinue;
if (ˆvalue_21 === true) {
{
const next_iter = _iterable_(next_fn, rest);
return [item, next_iter, next_ctx];
}
}
{
return [, _empty_iter_, next_ctx];
}
}
}
}
}
};
return items => _iterable_(next_fn, _iter_(items));
};
export const while_ac = while_fn => {
const next_fn = ([iterable, acc], ctx) => {
const [item, rest, m_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_23 = rest;
if (_is_done_(ˆvalue_23)) {
return [item, rest, m_ctx];
}
{
{
const [ˆcontinue, next_acc, next_ctx] = while_fn(item, acc, m_ctx);
{
const ˆvalue_25 = ˆcontinue;
if (ˆvalue_25 === true) {
{
const next_iter = _iterable_(next_fn, [rest, next_acc]);
return [item, next_iter, next_ctx];
}
}
{
return [, _empty_iter_, next_ctx];
}
}
}
}
}
};
return items => _iterable_(next_fn, [_iter_(items)]);
};
export const map = map_fn => {
const next_fn = (iterable, ctx) => {
const [item, rest, next_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_27 = rest;
if (_is_done_(ˆvalue_27)) {
return [item, rest, next_ctx];
}
{
{
const mapped_item = map_fn(item, undefined, next_ctx);
const next_iter = _iterable_(next_fn, rest);
return [mapped_item, next_iter, next_ctx];
}
}
}
};
return items => _iterable_(next_fn, _iter_(items));
};
export const map_ac = map_fn => {
const next_fn = ([iterable, acc], ctx) => {
const [item, rest, m_ctx = ctx] = _next_(iterable, ctx);
{
const ˆvalue_29 = rest;
if (_is_done_(ˆvalue_29)) {
return [item, rest, m_ctx];
}
{
{
const [mitem, next_acc, next_ctx = m_ctx] = map_fn(item, acc, m_ctx);
const next_iter = _iterable_(next_fn, [rest, next_acc]);
return [mitem, next_iter, next_ctx];
}
}
}
};
return items => _iterable_(next_fn, [_iter_(items)]);
};
export const chain = (...iterables) => iterable => {
const done = {};
const next_fn = (..._args5) => {
while (true) {
const [[curr = done, ...rest_iters], ctx] = _args5;
const ˆvalue_31 = curr;
if (ˆvalue_31 === done) {
return [, _empty_iter_, ctx];
}
{
{
const curr_iter = _iter_(curr);
const [item, rest_curr, next_ctx = ctx] = _next_(curr_iter, ctx);
{
const ˆvalue_33 = rest_curr;
if (_is_done_(ˆvalue_33)) {
_args5 = [rest_iters, next_ctx];
continue;
}
{
{
const next_iter = _iterable_(next_fn, [rest_curr, ...rest_iters]);
return [item, next_iter, next_ctx];
}
}
}
}
}
}
};
return _iterable_(next_fn, [iterable, ...iterables]);
};
export const flatten = iterables => {
const next_fn = (iters, ctx) => {
const [seq, rest_iters, seq_ctx = ctx] = _next_(iters, ctx);
{
let ˆpipe_result_35 = seq;
ˆpipe_result_35 = chain(flatten(rest_iters))(ˆpipe_result_35);
return ˆpipe_result_35 = _next_(ˆpipe_result_35, seq_ctx);
}
};
return _iterable_(next_fn, _iter_(iterables));
};
export const drop = num_items => filter_ac((ˆ_36, idx = 0) => [idx >= num_items, idx + 1]);
export const drop_last = num_items => iterable => {
let ˆpipe_result_37 = iterable;
ˆpipe_result_37 = map_ac((item, buffer = []) => {
const ˆvalue_38 = buffer;
if (num_items > length(ˆvalue_38)) {
return [[], [...buffer, item]];
}
{
{
const [out, ...rest] = buffer;
return [[out], [...rest, item]];
}
}
})(ˆpipe_result_37);
return ˆpipe_result_37 = flatten(ˆpipe_result_37);
};
export const take = num_items => iterable => {
const ˆvalue_40 = num_items;
if (ˆvalue_40 === 0) {
return [];
}
{
return while_ac((ˆ_42, ctr = 1) => [ctr <= num_items, ctr + 1])(iterable);
}
};
export const take_last = num_items => iterable => {
const last = {};
{
let ˆpipe_result_43 = iterable;
ˆpipe_result_43 = chain([last])(ˆpipe_result_43);
ˆpipe_result_43 = map_ac((item, buffer = []) => {
const ˆvalue_44 = item;
if (ˆvalue_44 === last) {
return [buffer, []];
}
{
{
const ˆvalue_46 = buffer;
if (num_items > length(ˆvalue_46)) {
return [[], [...buffer, item]];
}
{
{
const [, ...rest] = buffer;
return [[], [...rest, item]];
}
}
}
}
})(ˆpipe_result_43);
return ˆpipe_result_43 = flatten(ˆpipe_result_43);
}
};
export const slice = (start, end = max_int) => iterable => {
const ˆvalue_48 = true;
if (ˆvalue_48 === (end - start === 0)) {
return [];
}
if (ˆvalue_48 === (start < 0 && end < 0)) {
{
let ˆpipe_result_50 = iterable;
ˆpipe_result_50 = take_last(-start)(ˆpipe_result_50);
return ˆpipe_result_50 = drop_last(-end)(ˆpipe_result_50);
}
}
if (ˆvalue_48 === start < 0) {
{
let ˆpipe_result_51 = iterable;
ˆpipe_result_51 = take_last(-start)(ˆpipe_result_51);
return ˆpipe_result_51 = take(end + start)(ˆpipe_result_51);
}
}
if (ˆvalue_48 === end < 0) {
{
let ˆpipe_result_52 = iterable;
ˆpipe_result_52 = drop(start)(ˆpipe_result_52);
return ˆpipe_result_52 = drop_last(-end)(ˆpipe_result_52);
}
}
{
{
let ˆpipe_result_53 = iterable;
ˆpipe_result_53 = drop(start)(ˆpipe_result_53);
return ˆpipe_result_53 = take(end - start)(ˆpipe_result_53);
}
}
};
export const repeat = repititions => item => {
let ˆpipe_result_54 = undefined;
ˆpipe_result_54 = unfold(() => item)(ˆpipe_result_54);
return ˆpipe_result_54 = take(repititions)(ˆpipe_result_54);
};
export const count = (start, step = 1) => {
let ˆpipe_result_55 = start - step;
return ˆpipe_result_55 = unfold(value => value + step)(ˆpipe_result_55);
};
export const range = (start, end, step = 1) => {
let _do_result2;
ˆmatch_57: {
const ˆvalue_56 = end;
if (ˆvalue_56 != null) {
_do_result2 = [start, end];
break ˆmatch_57;
}
{
_do_result2 = [0, start];
break ˆmatch_57;
}
}
const [true_start, true_end] = _do_result2;
_do_result2 = undefined;
{
let ˆpipe_result_58 = true_start - step;
ˆpipe_result_58 = unfold(cntr => cntr + step)(ˆpipe_result_58);
return ˆpipe_result_58 = ˆwhile(cntr => cntr < true_end)(ˆpipe_result_58);
}
};
export const equals = (it1, it2) => {
const ˆvalue_59 = length(it1);
if (ˆvalue_59 !== length(it2)) {
return false;
}
{
{
let _do_result3;
{
let ˆpipe_result_61 = zip(it1, it2);
ˆpipe_result_61 = map(([item1, item2]) => item1 === item2)(ˆpipe_result_61);
_do_result3 = ˆpipe_result_61 = filter(found => !found)(ˆpipe_result_61);
}
const [eq = true] = _do_result3;
_do_result3 = undefined;
return eq;
}
}
};
export const enumerate = (start = 0, step = 1) => map_ac((item, cntr = start) => [[cntr, item], cntr + step]);
export const cycle = items => {
let ˆpipe_result_62 = items;
ˆpipe_result_62 = unfold(items => items)(ˆpipe_result_62);
return ˆpipe_result_62 = flatten(ˆpipe_result_62);
};
export const unique = filter_ac((item, known = []) => [!_in_(item, known), [...known, item]]);
export const insert_at = (idx, items) => iterable => {
const ignore = {};
{
let ˆpipe_result_63 = iterable;
ˆpipe_result_63 = chain([ignore])(ˆpipe_result_63);
ˆpipe_result_63 = map_ac((item, curr = 0) => {
let _do_result4;
ˆmatch_65: {
const ˆvalue_64 = curr;
if (ˆvalue_64 === idx) {
_do_result4 = chain([item])(items);
break ˆmatch_65;
}
{
_do_result4 = [item];
break ˆmatch_65;
}
}
const all = _do_result4;
_do_result4 = undefined;
return [all, curr + 1];
})(ˆpipe_result_63);
ˆpipe_result_63 = flatten(ˆpipe_result_63);
return ˆpipe_result_63 = filter(item => item !== ignore)(ˆpipe_result_63);
}
};
export const find_index = item_to_find => iterable => {
let _do_result5;
{
let ˆpipe_result_66 = iterable;
ˆpipe_result_66 = map_ac((item, idx = 0) => [[item, idx], idx + 1])(ˆpipe_result_66);
ˆpipe_result_66 = chain([[item_to_find, -1]])(ˆpipe_result_66);
_do_result5 = ˆpipe_result_66 = filter(([item]) => {
const ˆvalue_67 = item_to_find;
if (is_fn(ˆvalue_67)) {
return item_to_find(item);
}
if (ˆvalue_67 === item) {
return true;
}
{
return false;
}
})(ˆpipe_result_66);
}
const [[, idx]] = _do_result5;
_do_result5 = undefined;
return idx;
};
export const item_at = idx => iterable => {
const [item] = filter_ac((ˆ_69, curr_idx = 0) => [idx === curr_idx, curr_idx + 1])(iterable);
return item;
};
export const select = indices => iterable => map(idx => item_at(idx)(iterable))(indices);
export const compress = selectors => iterable => {
let ˆpipe_result_70 = zip(iterable, selectors);
ˆpipe_result_70 = filter(([, selected]) => selected)(ˆpipe_result_70);
return ˆpipe_result_70 = map(([item]) => item)(ˆpipe_result_70);
};
export const product = (...iterables) => {
const [iterable, ...rest] = iterables;
{
const ˆvalue_71 = rest;
if (0 === length(ˆvalue_71)) {
return map(item => [item])(iterable);
}
{
{
let ˆpipe_result_73 = iterable;
ˆpipe_result_73 = map(item => {
let _do_result6;
{
let ˆpipe_result_74 = rest;
ˆpipe_result_74 = product(...ˆpipe_result_74);
_do_result6 = ˆpipe_result_74 = map(items => [item, ...items])(ˆpipe_result_74);
}
const todo = _do_result6;
_do_result6 = undefined;
return todo;
})(ˆpipe_result_73);
return ˆpipe_result_73 = flatten(ˆpipe_result_73);
}
}
}
};
export const permutations = len => ([...iterable]) => {
const pool_len = length(iterable);
let _do_result7;
ˆmatch_76: {
const ˆvalue_75 = len;
if (ˆvalue_75 != null) {
_do_result7 = len;
break ˆmatch_76;
}
{
_do_result7 = pool_len;
break ˆmatch_76;
}
}
const expected_len = _do_result7;
_do_result7 = undefined;
const idx_range = range(pool_len);
{
let ˆpipe_result_77 = idx_range;
ˆpipe_result_77 = repeat(expected_len)(ˆpipe_result_77);
ˆpipe_result_77 = product(...ˆpipe_result_77);
ˆpipe_result_77 = map(indices => {
const ˆvalue_78 = unique(indices);
if (expected_len === length(ˆvalue_78)) {
return [[...select(indices)(iterable)]];
}
{
return [];
}
})(ˆpipe_result_77);
return ˆpipe_result_77 = flatten(ˆpipe_result_77);
}
};
export const combinations = len => ([...iterable]) => {
const pool_len = length(iterable);
const idx_range = range(pool_len);
{
let ˆpipe_result_80 = idx_range;
ˆpipe_result_80 = permutations(len)(ˆpipe_result_80);
ˆpipe_result_80 = map(indices => {
const ˆvalue_81 = indices;
if (equals(ˆvalue_81, sort()(indices))) {
return [[...select(indices)(iterable)]];
}
{
return [];
}
})(ˆpipe_result_80);
return ˆpipe_result_80 = flatten(ˆpipe_result_80);
}
};
export const pairs = iterable => {
let ˆpipe_result_83 = iterable;
ˆpipe_result_83 = map_ac((item, last = 0) => [[last, item], item])(ˆpipe_result_83);
return ˆpipe_result_83 = drop(1)(ˆpipe_result_83);
};
export const chunks = (len, fill) => iterable => {
const fill_items = repeat(len - 1)(fill);
{
let ˆpipe_result_84 = iterable;
ˆpipe_result_84 = chain(fill_items)(ˆpipe_result_84);
ˆpipe_result_84 = map_ac((item, group = []) => {
const items = [...group, item];
{
const ˆvalue_85 = items;
if (len === length(ˆvalue_85)) {
return [[items], []];
}
{
return [[], items];
}
}
})(ˆpipe_result_84);
return ˆpipe_result_84 = flatten(ˆpipe_result_84);
}
};