// ets_tracing: off // ets_tracing: off import { combinePar } from "../Cause/cause.js" import type { Exit } from "../Exit/exit.js" import type { Fiber } from "../Fiber/core.js" import { join } from "../Fiber/core.js" import type { FiberID } from "../Fiber/id.js" import { chain_, descriptorWith, halt } from "./core.js" import { raceWith_, transplant } from "./core-scope.js" import type { Effect } from "./effect.js" import { map_ } from "./map.js" /** * Sequentially zips this effect with the specified effect using the * specified combiner function. */ export function zipWithPar_( a: Effect, b: Effect, f: (a: A, b: A2) => B, __trace?: string ): Effect { const g = (b: A2, a: A) => f(a, b) return transplant((graft) => descriptorWith((d) => raceWith_( graft(a), graft(b), (ex, fi) => coordinateZipPar(d.id, f, true, ex, fi), (ex, fi) => coordinateZipPar(d.id, g, false, ex, fi), __trace ) ) ) } function coordinateZipPar( fiberId: FiberID, f: (a: X, b: Y) => B, leftWinner: boolean, winner: Exit, loser: Fiber ) { switch (winner._tag) { case "Success": { return map_(join(loser), (y) => f(winner.value, y)) } case "Failure": { return chain_(loser.interruptAs(fiberId), (e) => { switch (e._tag) { case "Success": { return halt(winner.cause) } case "Failure": { return leftWinner ? halt(combinePar(winner.cause, e.cause)) : halt(combinePar(e.cause, winner.cause)) } } }) } } } /** * Sequentially zips this effect with the specified effect using the * specified combiner function. */ export function zipWithPar( b: Effect, f: (a: A, b: A2) => B, __trace?: string ) { return (a: Effect): Effect => zipWithPar_(a, b, f, __trace) }