import * as A from "../Array";
import { map_ } from "./functor";
import type { Tree } from "./model";
import { chain_ } from "./monad";
/*
* -------------------------------------------
* Apply Tree
* -------------------------------------------
*/
export const mapBoth_ = (fa: Tree, fb: Tree, f: (a: A, b: B) => C): Tree => ({
value: f(fa.value, fb.value),
forest: A.comprehension([fa.forest, fb.forest], (a, b) => mapBoth_(a, b, f))
});
export const mapBoth = (fb: Tree, f: (a: A, b: B) => C) => (fa: Tree): Tree => mapBoth_(fa, fb, f);
export const ap_ = (fab: Tree<(a: A) => B>, fa: Tree): Tree => chain_(fab, (f) => map_(fa, (a) => f(a)));
export const ap = (fa: Tree) => (fab: Tree<(a: A) => B>): Tree => ap_(fab, fa);
export const apFirst_ = (fa: Tree, fb: Tree): Tree => mapBoth_(fa, fb, (a, _) => a);
export const apFirst = (fb: Tree) => (fa: Tree): Tree => apFirst_(fa, fb);
export const apSecond_ = (fa: Tree, fb: Tree): Tree => mapBoth_(fa, fb, (_, b) => b);