<T>(oldValue: T, newValue: T): (self: MutableRef<T>) => boolean
<T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanSets the value to newValue atomically if the current value equals oldValue. Returns true if the value was updated, false otherwise. Uses Effect's Equal interface for value comparison.
When to use
Use to replace a MutableRef value only when the current value still matches
an expected value.
Example (Comparing and setting values)
import { MutableRef } from "effect"
const ref = MutableRef.make("initial")
// Successful compare and set
const updated = MutableRef.compareAndSet(ref, "initial", "updated")
console.log(updated) // true
console.log(MutableRef.get(ref)) // "updated"
// Failed compare and set (value doesn't match)
const failed = MutableRef.compareAndSet(ref, "initial", "failed")
console.log(failed) // false
console.log(MutableRef.get(ref)) // "updated" (unchanged)
// Thread-safe counter increment
const counter = MutableRef.make(5)
let current: number
do {
current = MutableRef.get(counter)
} while (!MutableRef.compareAndSet(counter, current, current + 1))
// Pipe-able version
const casUpdate = MutableRef.compareAndSet("updated", "final")
console.log(casUpdate(ref)) // trueexport const const compareAndSet: {
<T>(oldValue: T, newValue: T): (
self: MutableRef<T>
) => boolean
<T>(
self: MutableRef<T>,
oldValue: T,
newValue: T
): boolean
}
Sets the value to newValue atomically if the current value equals oldValue.
Returns true if the value was updated, false otherwise.
Uses Effect's Equal interface for value comparison.
When to use
Use to replace a MutableRef value only when the current value still matches
an expected value.
Example (Comparing and setting values)
import { MutableRef } from "effect"
const ref = MutableRef.make("initial")
// Successful compare and set
const updated = MutableRef.compareAndSet(ref, "initial", "updated")
console.log(updated) // true
console.log(MutableRef.get(ref)) // "updated"
// Failed compare and set (value doesn't match)
const failed = MutableRef.compareAndSet(ref, "initial", "failed")
console.log(failed) // false
console.log(MutableRef.get(ref)) // "updated" (unchanged)
// Thread-safe counter increment
const counter = MutableRef.make(5)
let current: number
do {
current = MutableRef.get(counter)
} while (!MutableRef.compareAndSet(counter, current, current + 1))
// Pipe-able version
const casUpdate = MutableRef.compareAndSet("updated", "final")
console.log(casUpdate(ref)) // true
compareAndSet: {
<function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT>(oldValue: ToldValue: function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT, newValue: TnewValue: function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT): (self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface MutableRef<out T>A synchronous mutable reference that stores a current value.
When to use
Use to keep local mutable state in a stable, pipeable reference.
Details
Read or write the value directly through .current, or use the MutableRef
helpers for pipeable updates such as get, set, update, and
compareAndSet. All operations mutate the same reference in place.
Example (Creating and updating refs)
import { MutableRef } from "effect"
// Create a mutable reference
const ref: MutableRef.MutableRef<number> = MutableRef.make(42)
// Read the current value
console.log(ref.current) // 42
console.log(MutableRef.get(ref)) // 42
// Update the value
ref.current = 100
console.log(MutableRef.get(ref)) // 100
// Use with complex types
interface Config {
timeout: number
retries: number
}
const config: MutableRef.MutableRef<Config> = MutableRef.make({
timeout: 5000,
retries: 3
})
// Update through the interface
config.current = { timeout: 10000, retries: 5 }
console.log(config.current.timeout) // 10000
MutableRef<function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT>) => boolean
<function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT>(self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface MutableRef<out T>A synchronous mutable reference that stores a current value.
When to use
Use to keep local mutable state in a stable, pipeable reference.
Details
Read or write the value directly through .current, or use the MutableRef
helpers for pipeable updates such as get, set, update, and
compareAndSet. All operations mutate the same reference in place.
Example (Creating and updating refs)
import { MutableRef } from "effect"
// Create a mutable reference
const ref: MutableRef.MutableRef<number> = MutableRef.make(42)
// Read the current value
console.log(ref.current) // 42
console.log(MutableRef.get(ref)) // 42
// Update the value
ref.current = 100
console.log(MutableRef.get(ref)) // 100
// Use with complex types
interface Config {
timeout: number
retries: number
}
const config: MutableRef.MutableRef<Config> = MutableRef.make({
timeout: 5000,
retries: 3
})
// Update through the interface
config.current = { timeout: 10000, retries: 5 }
console.log(config.current.timeout) // 10000
MutableRef<function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT>, oldValue: ToldValue: function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT, newValue: TnewValue: function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT): boolean
} = import DualDual.const dual: <<T>(oldValue: T, newValue: T) => (self: MutableRef<T>) => boolean, <T>(self: MutableRef<T>, oldValue: T, newValue: T) => boolean>(arity: 3, body: <T>(self: MutableRef<T>, oldValue: T, newValue: T) => boolean) => (<T>(oldValue: T, newValue: T) => (self: MutableRef<T>) => boolean) & (<T>(self: MutableRef<T>, oldValue: T, newValue: T) => boolean) (+1 overload)dual<
<function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT>(oldValue: ToldValue: function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT, newValue: TnewValue: function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT) => (self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface MutableRef<out T>A synchronous mutable reference that stores a current value.
When to use
Use to keep local mutable state in a stable, pipeable reference.
Details
Read or write the value directly through .current, or use the MutableRef
helpers for pipeable updates such as get, set, update, and
compareAndSet. All operations mutate the same reference in place.
Example (Creating and updating refs)
import { MutableRef } from "effect"
// Create a mutable reference
const ref: MutableRef.MutableRef<number> = MutableRef.make(42)
// Read the current value
console.log(ref.current) // 42
console.log(MutableRef.get(ref)) // 42
// Update the value
ref.current = 100
console.log(MutableRef.get(ref)) // 100
// Use with complex types
interface Config {
timeout: number
retries: number
}
const config: MutableRef.MutableRef<Config> = MutableRef.make({
timeout: 5000,
retries: 3
})
// Update through the interface
config.current = { timeout: 10000, retries: 5 }
console.log(config.current.timeout) // 10000
MutableRef<function (type parameter) T in <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => booleanT>) => boolean,
<function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT>(self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface MutableRef<out T>A synchronous mutable reference that stores a current value.
When to use
Use to keep local mutable state in a stable, pipeable reference.
Details
Read or write the value directly through .current, or use the MutableRef
helpers for pipeable updates such as get, set, update, and
compareAndSet. All operations mutate the same reference in place.
Example (Creating and updating refs)
import { MutableRef } from "effect"
// Create a mutable reference
const ref: MutableRef.MutableRef<number> = MutableRef.make(42)
// Read the current value
console.log(ref.current) // 42
console.log(MutableRef.get(ref)) // 42
// Update the value
ref.current = 100
console.log(MutableRef.get(ref)) // 100
// Use with complex types
interface Config {
timeout: number
retries: number
}
const config: MutableRef.MutableRef<Config> = MutableRef.make({
timeout: 5000,
retries: 3
})
// Update through the interface
config.current = { timeout: 10000, retries: 5 }
console.log(config.current.timeout) // 10000
MutableRef<function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT>, oldValue: ToldValue: function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT, newValue: TnewValue: function (type parameter) T in <T>(self: MutableRef<T>, oldValue: T, newValue: T): booleanT) => boolean
>(3, (self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, oldValue: ToldValue, newValue: TnewValue) => {
if (import EqualEqual.function equals<T, T>(self: T, that: T): boolean (+1 overload)Checks whether two values are deeply structurally equal.
When to use
Use when you need Effect's default structural equality check.
Details
Returns a boolean and never throws. Primitives are compared by value, and
NaN equals NaN. Objects implementing Equal delegate to their
[Equal.symbol] method; if only one operand implements Equal, the result
is false.
Dates compare by ISO string, RegExps compare by string representation,
arrays compare element-by-element, Maps and Sets compare entries
order-independently, and plain objects compare enumerable keys recursively.
Functions without an Equal implementation compare by reference. Circular
references are handled when both structures are circular at the same depth.
Hash values are checked first as a fast-path rejection. The function also
supports dual data-last usage: call it with one argument to get a curried
predicate.
Gotchas
- Results are cached per object pair in a WeakMap. Objects must not be
mutated after their first comparison.
- Map and Set comparisons are O(n²) in size.
Example (Comparing values)
import { Equal } from "effect"
// Primitives
console.log(Equal.equals(1, 1)) // true
console.log(Equal.equals(NaN, NaN)) // true
console.log(Equal.equals("a", "b")) // false
// Objects and arrays
console.log(Equal.equals({ a: 1, b: 2 }, { a: 1, b: 2 })) // true
console.log(Equal.equals([1, [2, 3]], [1, [2, 3]])) // true
// Dates
console.log(Equal.equals(new Date("2024-01-01"), new Date("2024-01-01"))) // true
// Maps (order-independent)
const m1 = new Map([["a", 1], ["b", 2]])
const m2 = new Map([["b", 2], ["a", 1]])
console.log(Equal.equals(m1, m2)) // true
// Curried form
const is5 = Equal.equals(5)
console.log(is5(5)) // true
console.log(is5(3)) // false
equals(oldValue: ToldValue, self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.MutableRef<T>.current: Tcurrent)) {
self: MutableRef<T>(parameter) self: {
current: T;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.MutableRef<T>.current: Tcurrent = newValue: TnewValue
return true
}
return false
})