import * as O from "../../Option"; import * as Ex from "../Exit"; import * as C from "../Exit/Cause"; import { mapBothPar_ } from "../Task/apply-par"; import * as T from "./_internal/task"; import type { Fiber, SyntheticFiber } from "./model"; /** * Taskually maps over the value the fiber computes. */ export const mapTask_ = (fiber: Fiber, f: (a: A) => T.EIO): SyntheticFiber => ({ _tag: "SyntheticFiber", await: T.chain_(fiber.await, Ex.foreachTask(f)), getRef: (ref) => fiber.getRef(ref), inheritRefs: fiber.inheritRefs, interruptAs: (id) => T.chain_(fiber.interruptAs(id), Ex.foreachTask(f)), poll: T.chain_( fiber.poll, O.fold( () => T.pure(O.none()), (a) => T.map_(Ex.foreachTask_(a, f), O.some) ) ) }); /** * Taskually maps over the value the fiber computes. */ export const mapTask = (f: (a: A) => T.EIO) => (fiber: Fiber) => mapTask_(fiber, f); /** * Maps over the value the fiber computes. */ export const map_ = (fa: Fiber, f: (a: A) => B) => mapTask_(fa, (a) => T.pure(f(a))); /** * Maps over the value the fiber computes. */ export const map = (f: (a: A) => B) => (fa: Fiber) => map_(fa, f); /** * Zips this fiber with the specified fiber, combining their results using * the specified combiner function. Both joins and interruptions are performed * in sequential order from left to right. */ export const mapBoth_ = ( fa: Fiber, fb: Fiber, f: (a: A, b: A1) => B ): SyntheticFiber => ({ _tag: "SyntheticFiber", getRef: (ref) => T.mapBoth_(fa.getRef(ref), fb.getRef(ref), (a, b) => ref.join(a, b)), inheritRefs: T.chain_(fa.inheritRefs, () => fb.inheritRefs), interruptAs: (id) => T.mapBoth_(fa.interruptAs(id), fb.interruptAs(id), (ea, eb) => Ex.mapBothCause_(ea, eb, f, C.both)), poll: T.mapBoth_(fa.poll, fb.poll, (fa, fb) => O.chain_(fa, (ea) => O.map_(fb, (eb) => Ex.mapBothCause_(ea, eb, f, C.both))) ), await: T.result(mapBothPar_(T.chain_(fa.await, T.done), T.chain_(fb.await, T.done), f)) }); /** * Zips this fiber with the specified fiber, combining their results using * the specified combiner function. Both joins and interruptions are performed * in sequential order from left to right. */ export const mapBoth = (fb: Fiber, f: (a: A, b: B) => C) => (fa: Fiber) => mapBoth_(fa, fb, f); /** * Zips this fiber and the specified fiber together, producing a tuple of their output. */ export const both_ = (fa: Fiber, fb: Fiber) => mapBoth_(fa, fb, (a, b) => [a, b]); /** * Zips this fiber and the specified fiber together, producing a tuple of their output. */ export const both = (fb: Fiber) => (fa: Fiber) => both_(fa, fb); export const apFirst_ = (fa: Fiber, fb: Fiber) => mapBoth_(fa, fb, (a, _) => a); export const apFirst = (fb: Fiber) => (fa: Fiber) => apFirst_(fa, fb); export const apSecond_ = (fa: Fiber, fb: Fiber) => mapBoth_(fa, fb, (_, b) => b); export const apSecond = (fb: Fiber) => (fa: Fiber) => apSecond_(fa, fb);