# Sink.reduceEffect

Reduces values into a single result using an effectful function. Pass a `Ref<B>`;
after running, read the result with `Ref.get(ref)`. If the reducer effect fails,
the ref is left unchanged (Sink onSuccess is typed as never failing).

## Signatures

```ts
export declare function reduceEffect<A, B, E, E2, R2>(ref: Ref.Ref<B>, f: (b: B, a: A) => Effect.Effect<B, E2, R2>): Sink<A, E | E2, R2>;
```

## Why

Aggregation may require Effect services or asynchronous work while the result remains explicitly
available through a caller-owned Ref.

## Ownership and lifetime

The caller owns the Ref. Each success returns a lazy read/reduce/write Effect; invocation alone does
no work. The three steps are not one atomic operation. Serialized producers preserve execution
order, while overlapping executions can read the same value and commit in completion order.
Reducer failures, producer failures, and interrupted writes are ignored. Use
`withStateSemaphore` when the whole effectful transition must be serialized.

## Examples

```ts
import { Effect, Ref } from "effect"
import * as Sink from "@typed/fx/Sink"
const program = Effect.gen(function* () {
  const total = yield* Ref.make(0)
  return Sink.reduceEffect(total, (sum, n: number) => Effect.succeed(sum + n))
})
```
