EquivalenceBasedEqualityData.ts overview
Base class for value objects that derive Equal.Equal from a user-defined equivalence.
Mental model
Classextends|MData.Class`` and implementsEqual.Equal.-
Subclasses provide three pieces of behavior:
[isEquivalentToSymbol]— the semantic equivalence between two same-type instances.[hasSameTypeMarkerAsSymbol]— a runtime check that two values share the same type marker. Used as a guard before calling[isEquivalentToSymbol]. It is intentionally not declared as a TypeScript type guard because two instances of the same generic class may share a marker yet have different type parameters.[Hash.symbol]— a hash consistent with the equivalence; return0to disable hashing when the equivalence is cheaper than computing a hash.
Quickstart
Example (Equality by a single field)
import { Equal, Hash, Predicate } from "effect"
import * as MData from "@parischap/effect-lib/MData"
import * as MEquivalenceBasedEqualityData from "@parischap/effect-lib/MEquivalenceBasedEqualityData"
const moduleTag = "@example/UserId/"
const TypeId: unique symbol = Symbol.for(moduleTag) as TypeId
type TypeId = typeof TypeId
class UserId extends MEquivalenceBasedEqualityData.Class {
constructor(readonly value: number) {
super()
}
[MData.idSymbol]() {
return moduleTag
}
[MEquivalenceBasedEqualityData.hasSameTypeMarkerAsSymbol](that: unknown) {
return Predicate.hasProperty(that, TypeId)
}
[MEquivalenceBasedEqualityData.isEquivalentToSymbol](that: this) {
return this.value === that.value
}
[Hash.symbol]() {
return Hash.number(this.value)
}
protected get [TypeId](): TypeId {
return TypeId
}
}
console.log(Equal.equals(new UserId(1), new UserId(1))) // true
console.log(Equal.equals(new UserId(1), new UserId(2))) // false
Exports Grouped by Category
Model symbols
hasSameTypeMarkerAsSymbol
Symbol naming the runtime same-type-marker predicate. Subclasses implement it to gate the equivalence check and to keep generic instances from comparing equal across distinct type parameters.
Signature
declare const hasSameTypeMarkerAsSymbol: unique symbol
isEquivalentToSymbol
Symbol naming the user-defined equivalence between two same-type-marker instances.
Signature
declare const isEquivalentToSymbol: unique symbol
Models
Class (class)
Abstract base class adding Equal.Equal to | MData.Class``.
Signature
declare class Class
[isEquivalentToSymbol] (method)
Implements the equivalence between this and that. Called only after [hasSameTypeMarkerAsSymbol] confirmed that both share the same type marker.
Signature
declare const [isEquivalentToSymbol]: (this: this, that: this) => boolean
[hasSameTypeMarkerAsSymbol] (method)
Returns true when that has the same type marker as this. Not declared as a TypeScript type guard because two instances of the same generic class may share a marker yet differ in their type parameters.
Signature
declare const [hasSameTypeMarkerAsSymbol]: (that: unknown) => boolean
[Hash.symbol] (method)
Returns the hash of this. Return 0 to disable hashing when computing a real hash would be more expensive than evaluating the equivalence directly.
Signature
declare const [Hash.symbol]: () => number
[Equal.symbol] (method)
Implements Equal.Equal by combining the same-type-marker guard and the equivalence.
Signature
declare const [Equal.symbol]: (this: this, that: Equal.Equal) => boolean
Type (type alias)
Type of objects produced by this module.
Signature
type Type = MData.Type &
Equal.Equal & {
[isEquivalentToSymbol](this: Type, that: Type): boolean
[hasSameTypeMarkerAsSymbol](that: unknown): boolean
}
Module markers
moduleTag
Module tag.
Signature
declare const moduleTag: "@parischap/effect-lib/Data/EquivalenceBasedEqualityData/"