| 444 | |
| 445 | /** @internal */ |
| 446 | export const cachedFunction = <A, B, E, R>( |
| 447 | f: (a: A) => Effect.Effect<B, E, R>, |
| 448 | eq?: Equivalence<A> |
| 449 | ): Effect.Effect<(a: A) => Effect.Effect<B, E, R>> => { |
| 450 | return pipe( |
| 451 | core.sync(() => MutableHashMap.empty<Key<A>, Deferred.Deferred<readonly [FiberRefsPatch.FiberRefsPatch, B], E>>()), |
| 452 | core.flatMap(makeSynchronized), |
| 453 | core.map((ref) => (a: A) => |
| 454 | pipe( |
| 455 | ref.modifyEffect((map) => { |
| 456 | const result = pipe(map, MutableHashMap.get(new Key(a, eq))) |
| 457 | if (Option.isNone(result)) { |
| 458 | return pipe( |
| 459 | core.deferredMake<readonly [FiberRefsPatch.FiberRefsPatch, B], E>(), |
| 460 | core.tap((deferred) => |
| 461 | pipe( |
| 462 | effect.diffFiberRefs(f(a)), |
| 463 | core.intoDeferred(deferred), |
| 464 | fiberRuntime.fork |
| 465 | ) |
| 466 | ), |
| 467 | core.map((deferred) => [deferred, pipe(map, MutableHashMap.set(new Key(a, eq), deferred))] as const) |
| 468 | ) |
| 469 | } |
| 470 | return core.succeed([result.value, map] as const) |
| 471 | }), |
| 472 | core.flatMap(core.deferredAwait), |
| 473 | core.flatMap(([patch, b]) => pipe(effect.patchFiberRefs(patch), core.as(b))) |
| 474 | ) |
| 475 | ) |
| 476 | ) |
| 477 | } |
| 478 | |
| 479 | /** @internal */ |
| 480 | export const raceFirst = dual< |