message: improve foreachParN by killing fibers
diff: import { makeBy_ } from "../Array"
  +import { interrupt } from "../Fiber"
  import { pipe, tuple } from "../Function"
  import * as P from "../Promise"
  import * as Q from "../Queue"
  import { foldCauseM } from "."
  import { bracket } from "./bracket"
  -import { collectAllUnit } from "./collectAllUnit"
  +import { collectAll } from "./collectAll"
  import { chain, fork } from "./core"
  import * as D from "./do"
  import type { Effect } from "./effect"
  @@ -12,7 +13,9 @@ import { foreach } from "./foreach"
  import { foreachUnit } from "./foreachUnit"
  import { forever } from "./forever"
  import { map } from "./map"
  +import { sandbox } from "./sandbox"
  import { tap } from "./tap"
  +import { unsandbox } from "./unsandbox"
  /**
  * Applies the functionw `f` to each element of the `Iterable<A>` in parallel,
  @@ -43,7 +46,7 @@ export function foreachParN_(n: number) {
  )
  ),
  tap(({ pairs }) => pipe(pairs, foreachUnit(q.offer), fork)),
  - tap(({ pairs }) =>
  + D.bind("fibers", ({ pairs }) =>
  pipe(
  makeBy_(n, () =>
  pipe(
  @@ -65,13 +68,16 @@ export function foreachParN_(n: number) {
  fork
  )
  ),
  - collectAllUnit
  + collectAll
  )
  ),
  - D.bind("res", ({ pairs }) =>
  + D.bind("res", ({ fibers, pairs }) =>
  pipe(
  pairs,
  - foreach(([p]) => P.await(p))
  + foreach(([p]) => P.await(p)),
  + sandbox,
  + tap(() => pipe(fibers, foreach(interrupt))),
  + unsandbox
  )
  ),
  map(({ res }) => res)
  