functionalscript
Version:
FunctionalScript is a purely functional subset of JavaScript
100 lines (99 loc) • 3 kB
JavaScript
import { find } from "../find/module.f.js";
import { fold } from "../../list/module.f.js";
const b57 = b => b.length === 5 ? [b] : [[b[0], b[1], b[2]], b[3], [b[4], b[5], b[6]]];
const reduceOp = ([i, x]) => a => {
switch (i) {
case 0: {
switch (x.length) {
case 3: {
return [[...a, x[1], x[2]]];
}
case 5: {
return b57([...a, x[1], x[2], x[3], x[4]]);
}
}
}
case 2: {
switch (x.length) {
case 3: {
return [[x[0], x[1], ...a]];
}
case 5: {
return b57([x[0], x[1], ...a, x[3], x[4]]);
}
}
}
case 4: {
return b57([x[0], x[1], x[2], x[3], ...a]);
}
}
};
const reduceBranch = fold(reduceOp);
const nodeSet = (c) => (g) => (node) => {
const { first, tail } = find(c)(node);
const [i, x] = first;
const f = () => {
switch (i) {
case 0: {
// insert
const value = g(null);
switch (x.length) {
case 1: {
return [[value, x[0]]];
}
case 2: {
return [[value], x[0], [x[1]]];
}
}
}
case 1: {
// replace
switch (x.length) {
case 1: {
return [[g(x[0])]];
}
case 2: {
return [[g(x[0]), x[1]]];
}
case 3: {
return [[x[0], g(x[1]), x[2]]];
}
case 5: {
return [[x[0], g(x[1]), x[2], x[3], x[4]]];
}
}
}
case 2: {
// insert
const value = g(null);
switch (x.length) {
case 1: {
return [[x[0], value]];
}
case 2: {
return [[x[0]], value, [x[1]]];
}
}
}
case 3: {
// replace
switch (x.length) {
case 2: {
return [[x[0], g(x[1])]];
}
case 5: {
return [[x[0], x[1], x[2], g(x[3]), x[4]]];
}
}
}
case 4: {
// insert
const [v0, v1] = x;
return [[v0], v1, [g(null)]];
}
}
};
const r = reduceBranch(f())(tail);
return r.length === 1 ? r[0] : r;
};
export const set = c => f => tree => tree === null ? [f(null)] : nodeSet(c)(f)(tree);