import type { SequenceFn, TraverseFn, TraverseFn_ } from "@principia/prelude";
import { apF_, implementTraverse_ } from "@principia/prelude";
import type * as HKT from "@principia/prelude/HKT";
import * as A from "../Array";
import { identity } from "../Function";
import type { Forest, Tree, URI, V } from "./model";
/*
* -------------------------------------------
* Traversable Tree
* -------------------------------------------
*/
export const traverse_: TraverseFn_<[URI], V> = implementTraverse_<[URI], V>()((_) => (G) => {
const traverseG = A.traverse_(G);
const out = (ta: Tree, f: (a: A) => HKT.HKT): HKT.HKT> =>
apF_(G)(
G.map_(f(ta.value), (value) => (forest: Forest) => ({
value,
forest
})),
traverseG(ta.forest, (a) => out(a, f))
);
return out;
});
export const traverse: TraverseFn<[URI], V> = (G) => (f) => (ta) => traverse_(G)(ta, f);
export const sequence: SequenceFn<[URI], V> = (G) => (ta) => traverse_(G)(ta, identity);