TxHashSet.ts
TxHashSet.ts overview
Section titled “TxHashSet.ts overview”Transactional hash sets for storing unique values inside Effect transactions.
A TxHashSet keeps an immutable HashSet inside a TxRef, so membership
checks and updates can commit atomically with other transactional operations.
Use it when several pieces of shared transactional state must change
together, such as adding a value only after checking related state. The
module includes the usual set operations, including adding, removing,
membership checks, set algebra, mapping, filtering, reducing, and conversion
back to HashSet.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- combinators
- constructors
- converting
- elements
- filtering
- folding
- getters
- guards
- mapping
- models
- mutations
- utils
combinators
Section titled “combinators”difference
Section titled “difference”Creates the difference of two TxHashSets (elements in the first set that are not in the second), returning a new TxHashSet.
Example (Finding values absent from another set)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const set1 = yield* TxHashSet.make("a", "b", "c") const set2 = yield* TxHashSet.make("b", "d") const diff = yield* TxHashSet.difference(set1, set2)
const values = yield* TxHashSet.toHashSet(diff) console.log(Array.from(values).sort()) // ["a", "c"] console.log(yield* TxHashSet.size(diff)) // 2})Signature
declare const difference: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect.Effect<TxHashSet<V0>> <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect.Effect<TxHashSet<V0>>}Since v2.0.0
intersection
Section titled “intersection”Creates the intersection of two TxHashSets, returning a new TxHashSet.
Example (Finding common values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const set1 = yield* TxHashSet.make("a", "b", "c") const set2 = yield* TxHashSet.make("b", "c", "d") const common = yield* TxHashSet.intersection(set1, set2)
const values = yield* TxHashSet.toHashSet(common) console.log(Array.from(values).sort()) // ["b", "c"] console.log(yield* TxHashSet.size(common)) // 2})Signature
declare const intersection: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect.Effect<TxHashSet<V1 & V0>> <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect.Effect<TxHashSet<V0 & V1>>}Since v2.0.0
Creates the union of two TxHashSets, returning a new TxHashSet.
Example (Combining sets with union)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const set1 = yield* TxHashSet.make("a", "b") const set2 = yield* TxHashSet.make("b", "c") const combined = yield* TxHashSet.union(set1, set2)
const values = yield* TxHashSet.toHashSet(combined) console.log(Array.from(values).sort()) // ["a", "b", "c"] console.log(yield* TxHashSet.size(combined)) // 3})Signature
declare const union: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect.Effect<TxHashSet<V1 | V0>> <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect.Effect<TxHashSet<V0 | V1>>}Since v2.0.0
constructors
Section titled “constructors”Creates an empty TxHashSet.
Example (Creating an empty transactional hash set)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.empty<string>()
console.log(yield* TxHashSet.size(txSet)) // 0 console.log(yield* TxHashSet.isEmpty(txSet)) // true
// Add some values yield* TxHashSet.add(txSet, "hello") yield* TxHashSet.add(txSet, "world") console.log(yield* TxHashSet.size(txSet)) // 2})Signature
declare const empty: <V = never>() => Effect.Effect<TxHashSet<V>>Since v2.0.0
fromHashSet
Section titled “fromHashSet”Creates a TxHashSet from an existing HashSet.
Example (Creating a transactional hash set from a HashSet)
import { Effect, HashSet, TxHashSet } from "effect"
const program = Effect.gen(function* () { const hashSet = HashSet.make("x", "y", "z") const txSet = yield* TxHashSet.fromHashSet(hashSet)
console.log(yield* TxHashSet.size(txSet)) // 3 console.log(yield* TxHashSet.has(txSet, "y")) // true
// Original hashSet is unchanged when txSet is modified yield* TxHashSet.add(txSet, "w") console.log(HashSet.size(hashSet)) // 3 (original unchanged) console.log(yield* TxHashSet.size(txSet)) // 4})Signature
declare const fromHashSet: <V>(hashSet: HashSet.HashSet<V>) => Effect.Effect<TxHashSet<V>>Since v4.0.0
fromIterable
Section titled “fromIterable”Creates a TxHashSet from an iterable collection of values.
Example (Creating a transactional hash set from an iterable)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const fromArray = yield* TxHashSet.fromIterable(["a", "b", "c", "b", "a"]) console.log(yield* TxHashSet.size(fromArray)) // 3
const fromSet = yield* TxHashSet.fromIterable(new Set([1, 2, 3])) console.log(yield* TxHashSet.size(fromSet)) // 3
const fromString = yield* TxHashSet.fromIterable("hello") const values = yield* TxHashSet.toHashSet(fromString) console.log(Array.from(values).sort()) // ["e", "h", "l", "o"]})Signature
declare const fromIterable: <V>(values: Iterable<V>) => Effect.Effect<TxHashSet<V>>Since v2.0.0
Creates a TxHashSet from a variable number of values.
Example (Creating transactional hash sets from values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const fruits = yield* TxHashSet.make("apple", "banana", "cherry") console.log(yield* TxHashSet.size(fruits)) // 3
const numbers = yield* TxHashSet.make(1, 2, 3, 2, 1) // Duplicates ignored console.log(yield* TxHashSet.size(numbers)) // 3
const mixed = yield* TxHashSet.make("hello", 42, true) console.log(yield* TxHashSet.size(mixed)) // 3})Signature
declare const make: <Values extends ReadonlyArray<any>>(...values: Values) => Effect.Effect<TxHashSet<Values[number]>>Since v2.0.0
converting
Section titled “converting”toHashSet
Section titled “toHashSet”Converts the TxHashSet to an immutable HashSet snapshot.
Example (Taking a HashSet snapshot)
import { Effect, HashSet, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make("x", "y", "z") const hashSet = yield* TxHashSet.toHashSet(txSet)
console.log(HashSet.size(hashSet)) // 3 console.log(HashSet.has(hashSet, "y")) // true
// hashSet is a snapshot - modifications to txSet don't affect it yield* TxHashSet.add(txSet, "w") console.log(HashSet.size(hashSet)) // 3 (unchanged) console.log(yield* TxHashSet.size(txSet)) // 4})Signature
declare const toHashSet: <V>(self: TxHashSet<V>) => Effect.Effect<HashSet.HashSet<V>>Since v2.0.0
elements
Section titled “elements”Checks whether all values in the TxHashSet satisfy the predicate.
Example (Testing whether every value matches)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const numbers = yield* TxHashSet.make(2, 4, 6, 8)
console.log(yield* TxHashSet.every(numbers, (n) => n % 2 === 0)) // true console.log(yield* TxHashSet.every(numbers, (n) => n > 5)) // false
const empty = yield* TxHashSet.empty<number>() console.log(yield* TxHashSet.every(empty, (n) => n > 0)) // true (vacuously true)})Signature
declare const every: { <V>(predicate: Predicate<V>): (self: TxHashSet<V>) => Effect.Effect<boolean> <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect.Effect<boolean>}Since v4.0.0
Checks whether the TxHashSet contains the specified value.
Example (Checking membership)
import { Effect, Equal, Hash, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make("apple", "banana", "cherry")
console.log(yield* TxHashSet.has(txSet, "apple")) // true console.log(yield* TxHashSet.has(txSet, "grape")) // false
// Works with any type that implements Equal class Person implements Equal.Equal { constructor(readonly name: string) {}
[Equal.symbol](other: unknown) { return other instanceof Person && this.name === other.name }
[Hash.symbol](): number { return Hash.string(this.name) } }
const people = yield* TxHashSet.make(new Person("Alice"), new Person("Bob")) console.log(yield* TxHashSet.has(people, new Person("Alice"))) // true})Signature
declare const has: { <V>(value: V): (self: TxHashSet<V>) => Effect.Effect<boolean> <V>(self: TxHashSet<V>, value: V): Effect.Effect<boolean>}Since v2.0.0
isSubset
Section titled “isSubset”Checks whether a TxHashSet is a subset of another TxHashSet.
Example (Checking subset relationships)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const small = yield* TxHashSet.make("a", "b") const large = yield* TxHashSet.make("a", "b", "c", "d") const other = yield* TxHashSet.make("x", "y")
console.log(yield* TxHashSet.isSubset(small, large)) // true console.log(yield* TxHashSet.isSubset(large, small)) // false console.log(yield* TxHashSet.isSubset(small, other)) // false console.log(yield* TxHashSet.isSubset(small, small)) // true})Signature
declare const isSubset: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect.Effect<boolean> <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect.Effect<boolean>}Since v4.0.0
Checks whether at least one value in the TxHashSet satisfies the predicate.
Example (Testing whether some values match)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const numbers = yield* TxHashSet.make(1, 2, 3, 4, 5)
console.log(yield* TxHashSet.some(numbers, (n) => n > 3)) // true console.log(yield* TxHashSet.some(numbers, (n) => n > 10)) // false
const empty = yield* TxHashSet.empty<number>() console.log(yield* TxHashSet.some(empty, (n) => n > 0)) // false})Signature
declare const some: { <V>(predicate: Predicate<V>): (self: TxHashSet<V>) => Effect.Effect<boolean> <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect.Effect<boolean>}Since v4.0.0
filtering
Section titled “filtering”filter
Section titled “filter”Filters the TxHashSet keeping only values that satisfy the predicate, returning a new TxHashSet.
Example (Filtering values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const numbers = yield* TxHashSet.make(1, 2, 3, 4, 5, 6) const evens = yield* TxHashSet.filter(numbers, (n) => n % 2 === 0)
const values = yield* TxHashSet.toHashSet(evens) console.log(Array.from(values).sort()) // [2, 4, 6] console.log(yield* TxHashSet.size(evens)) // 3})Signature
declare const filter: { <V, U extends V>(refinement: Refinement<NoInfer<V>, U>): (self: TxHashSet<V>) => Effect.Effect<TxHashSet<U>> <V>(predicate: Predicate<NoInfer<V>>): (self: TxHashSet<V>) => Effect.Effect<TxHashSet<V>> <V, U extends V>(self: TxHashSet<V>, refinement: Refinement<V, U>): Effect.Effect<TxHashSet<U>> <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect.Effect<TxHashSet<V>>}Since v4.0.0
folding
Section titled “folding”reduce
Section titled “reduce”Reduces the TxHashSet to a single value by iterating through the values and applying an accumulator function.
Example (Reducing values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const numbers = yield* TxHashSet.make(1, 2, 3, 4, 5) const sum = yield* TxHashSet.reduce(numbers, 0, (acc, n) => acc + n)
console.log(sum) // 15
const strings = yield* TxHashSet.make("a", "b", "c") const concatenated = yield* TxHashSet.reduce(strings, "", (acc, s) => acc + s) console.log(concatenated) // Order may vary: "abc", "bac", etc.})Signature
declare const reduce: { <V, U>(zero: U, f: (accumulator: U, value: V) => U): (self: TxHashSet<V>) => Effect.Effect<U> <V, U>(self: TxHashSet<V>, zero: U, f: (accumulator: U, value: V) => U): Effect.Effect<U>}Since v2.0.0
getters
Section titled “getters”isEmpty
Section titled “isEmpty”Checks whether the TxHashSet is empty.
Example (Checking whether a set is empty)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const empty = yield* TxHashSet.empty<string>() console.log(yield* TxHashSet.isEmpty(empty)) // true
const nonEmpty = yield* TxHashSet.make("a") console.log(yield* TxHashSet.isEmpty(nonEmpty)) // false})Signature
declare const isEmpty: <V>(self: TxHashSet<V>) => Effect.Effect<boolean>Since v2.0.0
Returns the number of values in the TxHashSet.
Example (Getting the set size)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const empty = yield* TxHashSet.empty<string>() console.log(yield* TxHashSet.size(empty)) // 0
const small = yield* TxHashSet.make("a", "b") console.log(yield* TxHashSet.size(small)) // 2
const fromIterable = yield* TxHashSet.fromIterable(["x", "y", "z", "x", "y"]) console.log(yield* TxHashSet.size(fromIterable)) // 3 (duplicates ignored)})Signature
declare const size: <V>(self: TxHashSet<V>) => Effect.Effect<number>Since v2.0.0
guards
Section titled “guards”isTxHashSet
Section titled “isTxHashSet”Checks whether a value is a TxHashSet.
Example (Checking for a TxHashSet)
import { Effect, HashSet, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make(1, 2, 3) const hashSet = HashSet.make(1, 2, 3) const array = [1, 2, 3]
console.log(TxHashSet.isTxHashSet(txSet)) // true console.log(TxHashSet.isTxHashSet(hashSet)) // false console.log(TxHashSet.isTxHashSet(array)) // false console.log(TxHashSet.isTxHashSet(null)) // false})Signature
declare const isTxHashSet: (u: unknown) => u is TxHashSet<unknown>Since v4.0.0
mapping
Section titled “mapping”Maps each value in the TxHashSet using the provided function, returning a new TxHashSet.
Example (Mapping values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const numbers = yield* TxHashSet.make(1, 2, 3) const doubled = yield* TxHashSet.map(numbers, (n) => n * 2)
const values = yield* TxHashSet.toHashSet(doubled) console.log(Array.from(values).sort()) // [2, 4, 6] console.log(yield* TxHashSet.size(doubled)) // 3
// Mapping can reduce size if function produces duplicates const strings = yield* TxHashSet.make("apple", "banana", "cherry") const lengths = yield* TxHashSet.map(strings, (s) => s.length) const lengthValues = yield* TxHashSet.toHashSet(lengths) console.log(Array.from(lengthValues).sort()) // [5, 6] (apple=5, banana=6, cherry=6)})Signature
declare const map: { <V, U>(f: (value: V) => U): (self: TxHashSet<V>) => Effect.Effect<TxHashSet<U>> <V, U>(self: TxHashSet<V>, f: (value: V) => U): Effect.Effect<TxHashSet<U>>}Since v4.0.0
models
Section titled “models”TxHashSet (interface)
Section titled “TxHashSet (interface)”A TxHashSet is a transactional hash set data structure that provides atomic operations on unique values within Effect transactions. It uses an immutable HashSet internally with TxRef for transactional semantics, ensuring all operations are performed atomically.
Details
Mutation operations such as add, remove, and clear update the original TxHashSet and return Effect<void> or Effect<boolean>. Transform operations such as union, intersection, difference, map, and filter create new TxHashSet instances and leave the original TxHashSet unchanged.
Example (Using transactional hash sets)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { // Create a transactional hash set const txSet = yield* TxHashSet.make("apple", "banana", "cherry")
// Single operations are automatically transactional yield* TxHashSet.add(txSet, "grape") const hasApple = yield* TxHashSet.has(txSet, "apple") console.log(hasApple) // true
// Multi-step atomic operations yield* Effect.tx( Effect.gen(function* () { const hasCherry = yield* TxHashSet.has(txSet, "cherry") if (hasCherry) { yield* TxHashSet.remove(txSet, "cherry") yield* TxHashSet.add(txSet, "orange") } }) )
const size = yield* TxHashSet.size(txSet) console.log(size) // 4})Signature
export interface TxHashSet<in out V> extends Inspectable, Pipeable { readonly [TypeId]: typeof TypeId readonly ref: TxRef.TxRef<HashSet.HashSet<V>>}Since v4.0.0
mutations
Section titled “mutations”Adds a value to the TxHashSet. If the value already exists, the operation has no effect.
Details
This function mutates the original TxHashSet by adding the specified value. It does not return a new TxHashSet reference.
Example (Adding values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make("a", "b")
yield* TxHashSet.add(txSet, "c") console.log(yield* TxHashSet.size(txSet)) // 3 console.log(yield* TxHashSet.has(txSet, "c")) // true
// Adding existing value has no effect yield* TxHashSet.add(txSet, "a") console.log(yield* TxHashSet.size(txSet)) // 3 (unchanged)})Signature
declare const add: { <V>(value: V): (self: TxHashSet<V>) => Effect.Effect<void> <V>(self: TxHashSet<V>, value: V): Effect.Effect<void>}Since v2.0.0
Removes all values from the TxHashSet.
Details
This function mutates the original TxHashSet by clearing all values. It does not return a new TxHashSet reference.
Example (Clearing all values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make("a", "b", "c") console.log(yield* TxHashSet.size(txSet)) // 3
yield* TxHashSet.clear(txSet) console.log(yield* TxHashSet.size(txSet)) // 0 console.log(yield* TxHashSet.isEmpty(txSet)) // true})Signature
declare const clear: <V>(self: TxHashSet<V>) => Effect.Effect<void>Since v4.0.0
remove
Section titled “remove”Removes a value from the TxHashSet.
Details
This function mutates the original TxHashSet by removing the specified value. It does not return a new TxHashSet reference.
Example (Removing values)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { const txSet = yield* TxHashSet.make("a", "b", "c")
const removed = yield* TxHashSet.remove(txSet, "b") console.log(removed) // true (value existed and was removed) console.log(yield* TxHashSet.size(txSet)) // 2 console.log(yield* TxHashSet.has(txSet, "b")) // false
// Removing non-existent value returns false const notRemoved = yield* TxHashSet.remove(txSet, "d") console.log(notRemoved) // false})Signature
declare const remove: { <V>(value: V): (self: TxHashSet<V>) => Effect.Effect<boolean> <V>(self: TxHashSet<V>, value: V): Effect.Effect<boolean>}Since v2.0.0
TxHashSet (namespace)
Section titled “TxHashSet (namespace)”The TxHashSet namespace contains type-level utilities and helper types for working with TxHashSet instances.
Example (Extracting value types inside transactions)
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function* () { // Create a transactional color set const colors = yield* TxHashSet.make("red", "green", "blue")
// Extract the value type for reuse type Color = TxHashSet.TxHashSet.Value<typeof colors> // string
// Use extracted type in functions const addColor = (color: Color) => TxHashSet.add(colors, color)
yield* addColor("yellow")})Since v4.0.0
Value (type alias)
Section titled “Value (type alias)”Extracts the value type from a TxHashSet type.
Example (Extracting a TxHashSet value type)
import type { TxHashSet } from "effect"
type FruitSet = TxHashSet.TxHashSet<"apple" | "banana" | "cherry">
// Extract the value typetype Fruit = TxHashSet.TxHashSet.Value<FruitSet> // "apple" | "banana" | "cherry"
const processFruit = (fruit: Fruit) => { return `Processing ${fruit}`}
console.log(processFruit("apple")) // Processing appleSignature
type Value<T> = T extends TxHashSet<infer V> ? V : neverSince v4.0.0