TxHashSet
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.
Combinators
Creates the difference of two TxHashSets (elements in the first set that are not in the second), returning a new TxHashSet.
Signature
declare const difference: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect<TxHashSet<V0>>; <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect<TxHashSet<V0>>;}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)
Array.from(yield* TxHashSet.toHashSet(diff)).sort() // => ["a", "c"] yield* TxHashSet.size(diff) // => 2})
await Effect.runPromise(program)Creates the intersection of two TxHashSets, returning a new TxHashSet.
Signature
declare const intersection: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect<TxHashSet<V1 & V0>>; <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect<TxHashSet<V0 & V1>>;}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)
Array.from(yield* TxHashSet.toHashSet(common)).sort() // => ["b", "c"] yield* TxHashSet.size(common) // => 2})
await Effect.runPromise(program)Creates the union of two TxHashSets, returning a new TxHashSet.
Signature
declare const union: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect<TxHashSet<V1 | V0>>; <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect<TxHashSet<V0 | V1>>;}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)
Array.from(yield* TxHashSet.toHashSet(combined)).sort() // => ["a", "b", "c"] yield* TxHashSet.size(combined) // => 3})
await Effect.runPromise(program)Constructors
Creates an empty TxHashSet.
Signature
declare function empty<V = never>(): Effect<TxHashSet<V>>Example Creating an empty transactional hash set
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const txSet = yield* TxHashSet.empty<string>()
yield* TxHashSet.size(txSet) // => 0 yield* TxHashSet.isEmpty(txSet) // => true
// Add some values yield* TxHashSet.add(txSet, "hello") yield* TxHashSet.add(txSet, "world") yield* TxHashSet.size(txSet) // => 2})
await Effect.runPromise(program)Creates a TxHashSet from an existing HashSet.
Signature
declare function fromHashSet<V>(hashSet: HashSet<V>): Effect<TxHashSet<V>>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)
yield* TxHashSet.size(txSet) // => 3 yield* TxHashSet.has(txSet, "y") // => true
// Original hashSet is unchanged when txSet is modified yield* TxHashSet.add(txSet, "w") HashSet.size(hashSet) // => 3 yield* TxHashSet.size(txSet) // => 4})
await Effect.runPromise(program)Creates a TxHashSet from an iterable collection of values.
Signature
declare function fromIterable<V>(values: Iterable<V>): Effect<TxHashSet<V>>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"]) yield* TxHashSet.size(fromArray) // => 3
const fromSet = yield* TxHashSet.fromIterable(new Set([1, 2, 3])) yield* TxHashSet.size(fromSet) // => 3
const fromString = yield* TxHashSet.fromIterable("hello") Array.from(yield* TxHashSet.toHashSet(fromString)).sort() // => ["e", "h", "l", "o"]})
await Effect.runPromise(program)Creates a TxHashSet from a variable number of values.
Signature
declare function make<Values extends readonly Array<any>>(...values: Values): Effect<TxHashSet<Values[number]>>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") yield* TxHashSet.size(fruits) // => 3
const numbers = yield* TxHashSet.make(1, 2, 3, 2, 1) // Duplicates ignored yield* TxHashSet.size(numbers) // => 3
const mixed = yield* TxHashSet.make("hello", 42, true) yield* TxHashSet.size(mixed) // => 3})
await Effect.runPromise(program)Converting
Converts the TxHashSet to an immutable HashSet snapshot.
Signature
declare function toHashSet<V>(self: TxHashSet<V>): Effect<HashSet<V>>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)
HashSet.size(hashSet) // => 3 HashSet.has(hashSet, "y") // => true
// hashSet is a snapshot - modifications to txSet don't affect it yield* TxHashSet.add(txSet, "w") HashSet.size(hashSet) // => 3 yield* TxHashSet.size(txSet) // => 4})
await Effect.runPromise(program)Filtering
Filters the TxHashSet keeping only values that satisfy the predicate, returning a new TxHashSet.
Signature
declare const filter: { <V, U>(refinement: Refinement<NoInfer<V>, U>): (self: TxHashSet<V>) => Effect<TxHashSet<U>>; <V>(predicate: Predicate<NoInfer<V>>): (self: TxHashSet<V>) => Effect<TxHashSet<V>>; <V, U>(self: TxHashSet<V>, refinement: Refinement<V, U>): Effect<TxHashSet<U>>; <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect<TxHashSet<V>>;}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)
Array.from(yield* TxHashSet.toHashSet(evens)).sort() // => [2, 4, 6] yield* TxHashSet.size(evens) // => 3})
await Effect.runPromise(program)Folding
Reduces the TxHashSet to a single value by iterating through the values and applying an accumulator function.
Signature
declare const reduce: { <V, U>(zero: U, f: (accumulator: U, value: V) => U): (self: TxHashSet<V>) => Effect<U>; <V, U>(self: TxHashSet<V>, zero: U, f: (accumulator: U, value: V) => U): Effect<U>;}Example Reducing values
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const numbers = yield* TxHashSet.make(1, 2, 3, 4, 5) yield* TxHashSet.reduce(numbers, 0, (acc, n) => acc + n) // => 15
const strings = yield* TxHashSet.make("a", "b", "c") String(yield* TxHashSet.reduce(strings, "", (acc, s) => acc + s)).split("").sort().join("") // => "abc"})
await Effect.runPromise(program)Getters
Returns the number of values in the TxHashSet.
Signature
declare function size<V>(self: TxHashSet<V>): Effect<number>Example Getting the set size
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const empty = yield* TxHashSet.empty<string>() yield* TxHashSet.size(empty) // => 0
const small = yield* TxHashSet.make("a", "b") yield* TxHashSet.size(small) // => 2
const fromIterable = yield* TxHashSet.fromIterable(["x", "y", "z", "x", "y"]) yield* TxHashSet.size(fromIterable) // => 3})
await Effect.runPromise(program)Guards
Checks whether a value is a TxHashSet.
Signature
declare function isTxHashSet(u: unknown): u is TxHashSet<unknown>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]
TxHashSet.isTxHashSet(txSet) // => true TxHashSet.isTxHashSet(hashSet) // => false TxHashSet.isTxHashSet(array) // => false TxHashSet.isTxHashSet(null) // => false})
await Effect.runPromise(program)Mapping
Maps each value in the TxHashSet using the provided function, returning a new TxHashSet.
Signature
declare const map: { <V, U>(f: (value: V) => U): (self: TxHashSet<V>) => Effect<TxHashSet<U>>; <V, U>(self: TxHashSet<V>, f: (value: V) => U): Effect<TxHashSet<U>>;}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)
Array.from(yield* TxHashSet.toHashSet(doubled)).sort() // => [2, 4, 6] 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) Array.from(yield* TxHashSet.toHashSet(lengths)).sort() // => [5, 6]})
await Effect.runPromise(program)Models
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.
Signature
interface TxHashSet<in out V> extends Inspectable, Pipeable { readonly "~effect/TxHashSet": "~effect/TxHashSet"; readonly ref: TxRef<HashSet<V>>;}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") yield* TxHashSet.has(txSet, "apple") // => 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") } }) )
yield* TxHashSet.size(txSet) // => 4})
await Effect.runPromise(program)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.
Signature
declare const add: { <V>(value: V): (self: TxHashSet<V>) => Effect<void>; <V>(self: TxHashSet<V>, value: V): Effect<void>;}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") yield* TxHashSet.size(txSet) // => 3 yield* TxHashSet.has(txSet, "c") // => true
// Adding existing value has no effect yield* TxHashSet.add(txSet, "a") yield* TxHashSet.size(txSet) // => 3})
await Effect.runPromise(program)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.
Signature
declare function clear<V>(self: TxHashSet<V>): Effect<void>Example Clearing all values
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const txSet = yield* TxHashSet.make("a", "b", "c") yield* TxHashSet.size(txSet) // => 3
yield* TxHashSet.clear(txSet) yield* TxHashSet.size(txSet) // => 0 yield* TxHashSet.isEmpty(txSet) // => true})
await Effect.runPromise(program)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.
Signature
declare const remove: { <V>(value: V): (self: TxHashSet<V>) => Effect<boolean>; <V>(self: TxHashSet<V>, value: V): Effect<boolean>;}Example Removing values
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const txSet = yield* TxHashSet.make("a", "b", "c")
yield* TxHashSet.remove(txSet, "b") // => true yield* TxHashSet.size(txSet) // => 2 yield* TxHashSet.has(txSet, "b") // => false
// Removing non-existent value returns false yield* TxHashSet.remove(txSet, "d") // => false})
await Effect.runPromise(program)Other
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") yield* TxHashSet.has(colors, "yellow") // => true})
await Effect.runPromise(program)Predicates
Checks whether all values in the TxHashSet satisfy the predicate.
Signature
declare const every: { <V>(predicate: Predicate<V>): (self: TxHashSet<V>) => Effect<boolean>; <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect<boolean>;}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)
yield* TxHashSet.every(numbers, (n) => n % 2 === 0) // => true yield* TxHashSet.every(numbers, (n) => n > 5) // => false
const empty = yield* TxHashSet.empty<number>() yield* TxHashSet.every(empty, (n) => n > 0) // => true})
await Effect.runPromise(program)Checks whether the TxHashSet contains the specified value.
Signature
declare const has: { <V>(value: V): (self: TxHashSet<V>) => Effect<boolean>; <V>(self: TxHashSet<V>, value: V): Effect<boolean>;}Example Checking membership
import { Effect, Equal, Hash, TxHashSet } from "effect"
const program = Effect.gen(function*() { const txSet = yield* TxHashSet.make("apple", "banana", "cherry")
yield* TxHashSet.has(txSet, "apple") // => true 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")) yield* TxHashSet.has(people, new Person("Alice")) // => true})
await Effect.runPromise(program)Checks whether the TxHashSet is empty.
Signature
declare function isEmpty<V>(self: TxHashSet<V>): Effect<boolean>Example Checking whether a set is empty
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const empty = yield* TxHashSet.empty<string>() yield* TxHashSet.isEmpty(empty) // => true
const nonEmpty = yield* TxHashSet.make("a") yield* TxHashSet.isEmpty(nonEmpty) // => false})
await Effect.runPromise(program)Checks whether the TxHashSet is non-empty.
Signature
declare function isNonEmpty<V>(self: TxHashSet<V>): Effect<boolean>Example Checking whether a set is non-empty
import { Effect, TxHashSet } from "effect"
const program = Effect.gen(function*() { const empty = yield* TxHashSet.empty<string>() const emptyResult = yield* TxHashSet.isNonEmpty(empty)
const nonEmpty = yield* TxHashSet.make("a") const nonEmptyResult = yield* TxHashSet.isNonEmpty(nonEmpty) return [emptyResult, nonEmptyResult] as const})
await Effect.runPromise(program) // => [false, true]Checks whether a TxHashSet is a subset of another TxHashSet.
Signature
declare const isSubset: { <V1>(that: TxHashSet<V1>): <V0>(self: TxHashSet<V0>) => Effect<boolean>; <V0, V1>(self: TxHashSet<V0>, that: TxHashSet<V1>): Effect<boolean>;}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")
yield* TxHashSet.isSubset(small, large) // => true yield* TxHashSet.isSubset(large, small) // => false yield* TxHashSet.isSubset(small, other) // => false yield* TxHashSet.isSubset(small, small) // => true})
await Effect.runPromise(program)Checks whether at least one value in the TxHashSet satisfies the predicate.
Signature
declare const some: { <V>(predicate: Predicate<V>): (self: TxHashSet<V>) => Effect<boolean>; <V>(self: TxHashSet<V>, predicate: Predicate<V>): Effect<boolean>;}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)
yield* TxHashSet.some(numbers, (n) => n > 3) // => true yield* TxHashSet.some(numbers, (n) => n > 10) // => false
const empty = yield* TxHashSet.empty<number>() yield* TxHashSet.some(empty, (n) => n > 0) // => false})
await Effect.runPromise(program)