Skip to content
Effect Days 2026 Get your ticket

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.

23 exports Added in v2.0.0 Source

Combinators

difference

Added in v2.0.0 Source

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)

intersection

Added in v2.0.0 Source

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)

union

Added in v2.0.0 Source

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

empty

Added in v2.0.0 Source

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)

fromHashSet

Added in v4.0.0 Source

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)

fromIterable

Added in v2.0.0 Source

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)

make

Added in v2.0.0 Source

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

toHashSet

Added in v2.0.0 Source

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

filter

Added in v4.0.0 Source

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

reduce

Added in v2.0.0 Source

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

size

Added in v2.0.0 Source

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

isTxHashSet

Added in v4.0.0 Source

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

map

Added in v4.0.0 Source

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

TxHashSet interface

Added in v4.0.0 Source

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/transactions/TxHashSet": "~effect/transactions/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

add

Added in v2.0.0 Source

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)

clear

Added in v4.0.0 Source

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)

remove

Added in v2.0.0 Source

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

TxHashSet

Added in v4.0.0 Source

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

every

Added in v4.0.0 Source

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)

has

Added in v2.0.0 Source

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)

isEmpty

Added in v2.0.0 Source

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)

isSubset

Added in v4.0.0 Source

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)

some

Added in v4.0.0 Source

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)