Hyperlinkv0.8.0-beta.28

Ref

Ref.modifyconsteffect/Ref.ts:490
<A, B>(f: (a: A) => readonly [B, A]): (self: Ref<A>) => Effect.Effect<B>
<A, B>(self: Ref<A>, f: (a: A) => readonly [B, A]): Effect.Effect<B>

Modifies the value of the Ref atomically using the given function.

When to use

Use to compute both a separate return value and the next stored Ref value in one atomic update.

Details

The function receives the current value and returns a tuple of [result, newValue]. The Ref is updated with newValue, and result is returned by the effect.

Example (Modifying a value atomically)

import { Effect, Ref } from "effect"

const program = Effect.gen(function*() {
  const counter = yield* Ref.make(10)

  // Modify the ref and return some computation result
  const result = yield* Ref.modify(counter, (n) => [
    `Previous value was ${n}`, // Return value
    n * 2 // New ref value
  ])

  console.log(result) // "Previous value was 10"

  const current = yield* Ref.get(counter)
  console.log(current) // 20
})

// Example with more complex computation
const program2 = Effect.gen(function*() {
  const state = yield* Ref.make({ count: 0, total: 0 })

  const incremented = yield* Ref.modify(state, (s) => [
    s.count, // Return previous count
    { count: s.count + 1, total: s.total + s.count + 1 } // New state
  ])

  console.log(incremented) // 0
})
Source effect/Ref.ts:4909 lines
export const modify = dual<
  <A, B>(f: (a: A) => readonly [B, A]) => (self: Ref<A>) => Effect.Effect<B>,
  <A, B>(self: Ref<A>, f: (a: A) => readonly [B, A]) => Effect.Effect<B>
>(2, (self, f) =>
  Effect.sync(() => {
    const [b, a] = f(self.ref.current)
    self.ref.current = a
    return b
  }))
Referenced by 2 symbols