import * as A from "../Array"; import { identity } from "../Function"; import { map_ } from "./functor"; import type { Tree } from "./model"; /* * ------------------------------------------- * Monad Tree * ------------------------------------------- */ export const chain_ = (ma: Tree, f: (a: A) => Tree): Tree => { const { value, forest } = f(ma.value); const combine = A.getMonoid>().combine_; return { value, forest: combine( forest, A.map_(ma.forest, (a) => chain_(a, f)) ) }; }; export const chain = (f: (a: A) => Tree) => (ma: Tree): Tree => chain_(ma, f); export const flatten: (mma: Tree>) => Tree = chain(identity); export const tap_ = (ma: Tree, f: (a: A) => Tree): Tree => chain_(ma, (a) => map_(f(a), () => a)); export const tap = (f: (a: A) => Tree) => (ma: Tree): Tree => tap_(ma, f);