import type { Applicative, Monad } from "@principia/prelude";
import { chainF_, pureF } from "@principia/prelude";
import type * as HKT from "@principia/prelude/HKT";
import * as A from "../Array";
import type { Forest, Tree } from "./model";
export const make = (value: A, forest: Forest): Tree => ({
value,
forest
});
/**
* Build a tree from a seed value
*
* @category constructors
* @since 1.0.0
*/
export function unfoldTree(b: B, f: (b: B) => [A, Array]): Tree {
const [a, bs] = f(b);
return { value: a, forest: unfoldForest(bs, f) };
}
/**
* Build a tree from a seed value
*
* @category constructors
* @since 1.0.0
*/
export function unfoldForest(bs: Array, f: (b: B) => [A, Array]): Forest {
return bs.map((b) => unfoldTree(b, f));
}
export function unfoldTreeM(
M: Applicative & Monad
): (
b: B,
f: (b: B) => HKT.Kind]>
) => HKT.Kind>;
export function unfoldTreeM(
M: Applicative> & Monad>
): (b: B, f: (b: B) => HKT.HKT]>) => HKT.HKT> {
const unfoldForestMM = unfoldForestM(M);
const chain = chainF_(M);
const pure = pureF(M);
return (b, f) => chain(f(b), ([a, bs]) => chain(unfoldForestMM(bs, f), (ts) => pure({ value: a, forest: ts })));
}
export function unfoldForestM(
M: Applicative & Monad
): (
bs: ReadonlyArray,
f: (b: B) => HKT.Kind]>
) => HKT.Kind>;
export function unfoldForestM(
M: Applicative> & Monad>
): (bs: ReadonlyArray, f: (b: B) => HKT.HKT]>) => HKT.HKT> {
const traverseM = A.traverse_(M);
return (bs, f) => traverseM(bs, (b) => unfoldTreeM(M)(b, f));
}