import type { Monoid } from "@principia/prelude/Monoid"; import type { Tree } from "./model"; /* * ------------------------------------------- * Foldable Tree * ------------------------------------------- */ export const reduce_ = (fa: Tree, b: B, f: (b: B, a: A) => B): B => { let r: B = f(b, fa.value); const len = fa.forest.length; for (let i = 0; i < len; i++) { r = reduce_(fa.forest[i], r, f); } return r; }; export const reduce = (b: B, f: (b: B, a: A) => B) => (fa: Tree): B => reduce_(fa, b, f); export const reduceRight_ = (fa: Tree, b: B, f: (a: A, b: B) => B): B => { let r: B = b; const len = fa.forest.length; for (let i = len - 1; i >= 0; i--) { r = reduceRight_(fa.forest[i], r, f); } return f(fa.value, r); }; export const reduceRight = (b: B, f: (a: A, b: B) => B) => (fa: Tree): B => reduceRight_(fa, b, f); export const foldMap_ = (M: Monoid) => (fa: Tree, f: (a: A) => M): M => reduce_(fa, M.nat, (acc, a) => M.combine_(acc, f(a))); export const foldMap = (M: Monoid) => (f: (a: A) => M) => (fa: Tree) => foldMap_(M)(fa, f);