Import
import { tapEffect } from "@typed/fx/Sink";Signatures
export declare const tapEffect: {
<A, E2, R2>(f: (a: A) => Effect.Effect<unknown, E2, R2>): <E, R>(sink: Sink<A, E | E2, R>) => Sink<A, E | E2, R | R2>;
<A, E, R, E2, R2>(sink: Sink<A, E | E2, R>, f: (a: A) => Effect.Effect<unknown, E2, R2>): Sink<A, E | E2, R | R2>;
};Why
Logging, metrics, and other observations can be attached at the consumer boundary without changing the value type.
Ownership and lifetime
The tap Effect completes before the value is forwarded. If it fails, its Cause is delivered and the value is not forwarded. The producer controls call order and concurrency; tap services and interruption are reflected by the returned sink.
Examples
import { Effect } from "effect"
import * as Sink from "@typed/fx/Sink"
const observed = Sink.tapEffect(Sink.make(Effect.logError, Effect.log), (n: number) => Effect.log(`saw ${n}`))Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.