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)); }