Hash.ts
Hash.ts overview
Section titled “Hash.ts overview”Computes Effect hash values and defines the interface for objects that want to provide their own hash implementation. Hashes are small numeric fingerprints used by Effect data structures to bucket values quickly; they are not cryptographic digests and they are not proof that two values are equal. The module also includes helpers for primitive, structure, array, and reference-based hashes, plus functions for combining and optimizing numeric hash values.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”guards
Section titled “guards”isHash
Section titled “isHash”Checks whether a value implements the Hash interface.
When to use
Use to detect whether an unknown value provides a custom hash implementation.
Details
This function determines whether a given value has the Hash symbol property, indicating that it can provide its own hash value implementation.
Example (Checking for Hash support)
import { Hash } from "effect"
class MyHashable implements Hash.Hash { [Hash.symbol]() { return 42 }}
const obj = new MyHashable()console.log(Hash.isHash(obj)) // trueconsole.log(Hash.isHash({})) // falseconsole.log(Hash.isHash("string")) // falseSignature
declare const isHash: (u: unknown) => u is HashSince v2.0.0
hashing
Section titled “hashing”Computes a hash value for an iterable by hashing all of its elements.
When to use
Use to hash the values yielded by an iterable with Effect hash semantics.
Details
The implementation folds element hashes from the seed 6151 with XOR and
then optimizes the final hash.
Gotchas
A hash is not an equality proof. Because this implementation uses XOR, reordered inputs can produce the same hash.
Example (Hashing arrays)
import { Hash } from "effect"
const arr1 = [1, 2, 3]const arr2 = [1, 2, 3]const arr3 = [3, 2, 1]
console.log(Hash.array(arr1)) // hash of [1, 2, 3]console.log(Hash.array(arr2)) // same hash as arr1console.log(Hash.array(arr3)) // may match reordered inputs
console.log(Hash.array(arr1) === Hash.array(arr2)) // trueconsole.log(Hash.array(arr1) === Hash.array(arr3)) // trueSee
hashfor the general-purpose hash dispatcher
Signature
declare const array: <A>(arr: Iterable<A>) => numberSince v2.0.0
combine
Section titled “combine”Combines two hash values into a single hash value.
When to use
Use to build a hash for a composite value by folding together hash values for its parts.
Details
Supports both direct and pipeable usage. The implementation combines two
hash values with (self * 53) ^ b.
Example (Combining hash values)
import { Hash, pipe } from "effect"
// Can also be used with pipe
const hash1 = Hash.hash("hello")const hash2 = Hash.hash("world")
// Combine two hash valuesconst combined = Hash.combine(hash2)(hash1)console.log(combined)const result = pipe(hash1, Hash.combine(hash2))See
hashfor computing hash values from arbitrary inputsstructureKeysfor hashing selected object fields without manual combination
Signature
declare const combine: { (b: number): (self: number) => number; (self: number, b: number): number }Since v2.0.0
Computes a hash value for any given value.
When to use
Use to compute an Effect hash for primitives, collections, and hashable objects.
Details
This function can hash primitives (numbers, strings, booleans, etc.) as well as objects, arrays, and other complex data structures. It automatically handles different types and provides a consistent hash value for equivalent inputs.
Gotchas
Objects being hashed must be treated as immutable after their first hash
computation. Hash results are cached, so mutating an object after hashing will
lead to stale cached values and broken hash-based operations. For mutable
objects, implement a custom Hash interface that hashes the object reference
rather than its content.
Example (Hashing different values)
import { Hash } from "effect"
// Hash primitive valuesconsole.log(Hash.hash(42)) // numeric hashconsole.log(Hash.hash("hello")) // string hashconsole.log(Hash.hash(true)) // boolean hash
// Hash objects and arraysconsole.log(Hash.hash({ name: "John", age: 30 }))console.log(Hash.hash([1, 2, 3]))console.log(Hash.hash({ id: "user-1", roles: ["admin", "editor"] }))Signature
declare const hash: <A>(self: A) => numberSince v2.0.0
number
Section titled “number”Computes a hash value for a number.
When to use
Use to hash a JavaScript number with Effect’s numeric hash semantics.
Details
This function creates a hash value for numeric inputs, handling special cases like NaN, Infinity, and -Infinity with distinct hash values. It uses bitwise operations to ensure good distribution of hash values across different numeric inputs.
Example (Hashing numbers)
import { Hash } from "effect"
console.log(Hash.number(42)) // hash of 42console.log(Hash.number(3.14)) // hash of 3.14console.log(Hash.number(NaN)) // hash of "NaN"console.log(Hash.number(Infinity)) // 0 (special case)
// Same numbers produce the same hashconsole.log(Hash.number(100) === Hash.number(100)) // trueSignature
declare const number: (n: number) => numberSince v2.0.0
optimize
Section titled “optimize”Applies bit manipulation techniques to optimize a hash value.
When to use
Use to improve the bit distribution of a raw numeric hash value.
Details
This function takes a hash value and applies bitwise operations to improve the distribution of hash values, reducing the likelihood of collisions.
Example (Optimizing a hash value)
import { Hash } from "effect"
const rawHash = 1234567890const optimizedHash = Hash.optimize(rawHash)console.log(optimizedHash) // optimized hash value
// Often used internally by other hash functionsconst stringHash = Hash.optimize(Hash.string("hello"))Signature
declare const optimize: (n: number) => numberSince v2.0.0
random
Section titled “random”Generates a random hash value for an object and caches it.
When to use
Use to hash an object by reference identity instead of structural content.
Details
This function creates a random hash value for objects that don’t have their own hash implementation. The hash value is cached using a WeakMap, so the same object will always return the same hash value during its lifetime.
Example (Hashing objects by reference)
import { Hash } from "effect"
const obj1 = { a: 1 }const obj2 = { a: 1 }
// Same object always returns the same hashconsole.log(Hash.random(obj1) === Hash.random(obj1)) // true
// Different objects get different hashesconsole.log(Hash.random(obj1) === Hash.random(obj2)) // falseSignature
declare const random: <A extends object>(self: A) => numberSince v2.0.0
string
Section titled “string”Computes a hash value for a string using the djb2 algorithm.
When to use
Use when you need a string field to contribute to a custom structural hash implementation.
Details
This function implements a variation of the djb2 hash algorithm, which is known for its good distribution properties and speed. It processes each character of the string to produce a consistent hash value.
Example (Hashing strings)
import { Hash } from "effect"
console.log(Hash.string("hello")) // hash of "hello"console.log(Hash.string("world")) // hash of "world"console.log(Hash.string("")) // hash of empty string
// Same strings produce the same hashconsole.log(Hash.string("test") === Hash.string("test")) // trueSignature
declare const string: (str: string) => numberSince v2.0.0
structure
Section titled “structure”Computes a structural hash for an object using Effect’s object key collection.
When to use
Use to hash an object from all structural keys collected by Effect.
Details
The hash is based on the object’s structural keys and their values, including symbol keys and relevant prototype keys for non-plain objects.
Example (Hashing object structures)
import { Hash } from "effect"
const obj1 = { name: "John", age: 30 }const obj2 = { name: "Jane", age: 25 }const obj3 = { name: "John", age: 30 }
console.log(Hash.structure(obj1)) // hash of obj1console.log(Hash.structure(obj2)) // different hashconsole.log(Hash.structure(obj3)) // same as obj1
// Objects with same properties produce same hashconsole.log(Hash.structure(obj1) === Hash.structure(obj3)) // trueSignature
declare const structure: <A extends object>(o: A) => numberSince v2.0.0
structureKeys
Section titled “structureKeys”Computes a hash value for an object using only the specified keys.
When to use
Use to hash an object by a selected set of property keys.
Details
This function allows you to hash an object by considering only specific keys, which is useful when you want to create a hash based on a subset of an object’s properties.
Example (Hashing selected object keys)
import { Hash } from "effect"
const person = { name: "John", age: 30, city: "New York" }
// Hash only specific keysconst hash1 = Hash.structureKeys(person, ["name", "age"])const hash2 = Hash.structureKeys(person, ["name", "city"])
console.log(hash1) // hash based on name and ageconsole.log(hash2) // hash based on name and city
// Same keys produce the same hashconst person2 = { name: "John", age: 30, city: "Boston" }const hash3 = Hash.structureKeys(person2, ["name", "age"])console.log(hash1 === hash3) // trueSignature
declare const structureKeys: (o: object, keys: Iterable<PropertyKey>) => numberSince v2.0.0
models
Section titled “models”Hash (interface)
Section titled “Hash (interface)”A type that represents an object that can be hashed.
When to use
Use to let a custom type provide its own stable hash value.
Details
Objects implementing this interface provide a method to compute their hash value, which is used for efficient comparison and storage operations.
Example (Implementing Hash)
import { Hash } from "effect"
class MyClass implements Hash.Hash { constructor(private value: number) {}
[Hash.symbol](): number { return Hash.hash(this.value) }}
const instance = new MyClass(42)console.log(instance[Hash.symbol]()) // hash value of 42Signature
export interface Hash { [symbol](): number}Since v2.0.0
symbols
Section titled “symbols”symbol
Section titled “symbol”Defines the unique identifier used to identify objects that implement the Hash interface.
When to use
Use as the computed property key for the method that supplies a custom hash
value on a Hash implementor.
See
Hashfor the interface implemented with this symbolisHashfor checking whether a value implementsHashhashfor computing hash values
Signature
declare const symbol: "~effect/interfaces/Hash"Since v2.0.0