FingerTreeIndexed = {
const foldl = (op, z) => v => (v.foldl === undefined) ? op(z,v) : v.foldl(op, z);
const size = v => (v.size === undefined) ? 1 : v.size;
const at = a => i => i < 0 || i >= size(a) ? undefined : (a.at != undefined) ? a.at(i) : i === 0 ? a : undefined;
const at2 = (a,b) => i => i < size(a) ? at(a)(i) : at(b)(i - size(a));
const at3 = (a,b,c) => i => i < size(a) ? at(a)(i) : at2(b,c)(i - size(a));
const at4 = (a,b,c,d) => i => i < size(a) ? at(a)(i) : at3(b,c,d)(i - size(a));
var digit1, digit2, digit3, digit4, node2, node3, empty, single, tree;
tree = (left, subtree, right) => ({
st: subtree,
toString: () => `tree(${left},${subtree},${right})`,
cons: a => (left.cons)(a)(subtree, right),
snoc: a => (right.snoc)(a)(left, subtree),
foldl: (op,z) => op(op(op(z, foldl(op,z)(left)), foldl(op,z)(subtree)), foldl(op,z)(right)),
size: left.size + subtree.size + right.size,
at: at3(left, subtree, right)
});
single = a => ({
toString: () => `single(${a})`,
cons: b => (tree(digit1(b), empty, digit1(a))),
snoc: b => (tree(digit1(a), empty, digit1(b))),
foldl: (op,z) => foldl(op,z)(a),
size: size(a),
at: at(a)
});
empty = {
toString: () => "<>",
cons: single,
snoc: single,
foldl: (op,z) => z,
size: 0,
at: i => undefined
};
digit1 = a => ({
toString: () => `[${a}]`,
cons: b => (subtree, right) => tree(digit2(b,a), subtree, right),
snoc: b => (left, subtree) => tree(left, subtree, digit2(a,b)),
foldl: (op,z) => foldl(op,z)(a),
size: size(a),
at: at(a)
});
digit2 = (a,b) => ({
toString: () => `[${a},${b}]`,
cons: c => (subtree, right) => tree(digit3(c,a,b), subtree, right),
snoc: c => (left, subtree) => tree(left, subtree, digit3(a,b,c)),
foldl: (op,z) => op(foldl(op,z)(a),foldl(op,z)(b)),
size: size(a) + size(b),
at: at2(a,b)
});
digit3 = (a,b,c) => ({
toString: () => `[${a},${b},${c}]`,
cons: d => (subtree, right) => tree(digit4(d,a,b,c), subtree, right),
snoc: d => (left, subtree) => tree(left, subtree, digit4(a,b,c,d)),
foldl: (op,z) => op(op(foldl(op,z)(a),foldl(op,z)(b)),foldl(op,z)(c)),
size: size(a) + size(b) + size(c),
at: at3(a,b,c)
});
digit4 = (a,b,c,d) => ({
toString: () => `[${a},${b},${c},${d}]`,
cons: e => (subtree, right) => tree(digit2(e,a), subtree.cons(node3(b,c,d)), right),
snoc: e => (left, subtree) => tree(left, subtree.snoc(node3(a,b,c)), digit2(d,e)),
foldl: (op,z) => op(op(op(foldl(op,z)(a),foldl(op,z)(b)),foldl(op,z)(c)),foldl(op,z)(d)),
size: size(a) + size(b) + size(c) + size(d),
at: at4(a,b,c,d)
});
node2 = (a,b) => ({
toString: () => `node(${a},${b})`,
foldl: (op,z) => op(op(z,foldl(op,z)(a)),foldl(op,z)(b)),
size: size(a) + size(b),
at: at2(a,b)
});
node3 = (a,b,c) => ({
toString: () => `node(${a},${b},${c})`,
foldl: (op,z) => op(op(op(z,foldl(op,z)(a)),foldl(op,z)(b)),foldl(op,z)(c)),
size: size(a) + size(b) + size(c),
at: at3(a,b,c)
})
return {
empty: empty,
single: single,
tree: tree,
digit1: digit1,
digit2: digit2,
digit3: digit3,
digit4: digit4,
node2: node2,
node3: node3,
}
}