Hyperlinkv0.8.0-beta.28

Effect

Effect.tapconsteffect/Effect.ts:2135
<A, B, E2, R2>(f: (a: NoInfer<A>) => Effect<B, E2, R2>): <E, R>(
  self: Effect<A, E, R>
) => Effect<A, E | E2, R | R2>
<B, E2, R2>(f: Effect<B, E2, R2>): <A, E, R>(
  self: Effect<A, E, R>
) => Effect<A, E | E2, R | R2>
<A, E, R, B, E2, R2>(
  self: Effect<A, E, R>,
  f: (a: NoInfer<A>) => Effect<B, E2, R2>
): Effect<A, E | E2, R | R2>
<A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: Effect<B, E2, R2>): Effect<
  A,
  E | E2,
  R | R2
>

Runs a side effect with the result of an effect without changing the original value.

When to use

Use when you need to run an effectful observation, such as logging or tracking, while passing the original success value to the next step.

Details

tap works similarly to flatMap, but it ignores the result of the function passed to it. The value from the previous effect remains available for the next part of the chain. Note that if the side effect fails, the entire chain will fail too.

Example (Logging a step in a pipeline)

import { Console, Data, Effect, pipe } from "effect"

class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}

// Function to apply a discount safely to a transaction amount
const applyDiscount = (
  total: number,
  discountRate: number
): Effect.Effect<number, DiscountRateError> =>
  discountRate === 0
    ? Effect.fail(new DiscountRateError())
    : Effect.succeed(total - (total * discountRate) / 100)

// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))

const finalAmount = pipe(
  fetchTransactionAmount,
  // Log the fetched transaction amount
  Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
  // `amount` is still available!
  Effect.flatMap((amount) => applyDiscount(amount, 5))
)

Effect.runPromise(finalAmount).then(console.log)
// Output:
// Apply a discount to: 100
// 95
sequencing
Source effect/Effect.ts:213516 lines
export const tap: {
  <A, B, E2, R2>(
    f: (a: NoInfer<A>) => Effect<B, E2, R2>
  ): <E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2>
  <B, E2, R2>(
    f: Effect<B, E2, R2>
  ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2>
  <A, E, R, B, E2, R2>(
    self: Effect<A, E, R>,
    f: (a: NoInfer<A>) => Effect<B, E2, R2>
  ): Effect<A, E | E2, R | R2>
  <A, E, R, B, E2, R2>(
    self: Effect<A, E, R>,
    f: Effect<B, E2, R2>
  ): Effect<A, E | E2, R | R2>
} = internal.tap
Referenced by 10 symbols