From b1c3409839edfa30c3500eee8b1500cae3f822c9 Mon Sep 17 00:00:00 2001 From: Michael Arnaldi Date: Tue, 4 Oct 2022 16:58:48 +0000 Subject: [PATCH] chore: improve object equality, fix eval and tag --- .changeset/weak-melons-ring.md | 5 ++++ packages/stdlib/_src/io/Eval/definition.ts | 30 +++++++++++++++++++--- packages/stdlib/_src/service/Tag.ts | 8 +++++- packages/stdlib/_src/structure/Equals.ts | 9 +++++++ 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 .changeset/weak-melons-ring.md diff --git a/.changeset/weak-melons-ring.md b/.changeset/weak-melons-ring.md new file mode 100644 index 00000000..e935c70d --- /dev/null +++ b/.changeset/weak-melons-ring.md @@ -0,0 +1,5 @@ +--- +"@tsplus/stdlib": patch +--- + +Improve Equals on Object, fix Tag/Eval equality diff --git a/packages/stdlib/_src/io/Eval/definition.ts b/packages/stdlib/_src/io/Eval/definition.ts index 6c5a44a7..ad7b3b10 100644 --- a/packages/stdlib/_src/io/Eval/definition.ts +++ b/packages/stdlib/_src/io/Eval/definition.ts @@ -49,33 +49,57 @@ export function unifyEval>( } export interface Succeed extends Eval {} -export class Succeed { +export class Succeed implements Equals { readonly _tag = "Succeed" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly a: Lazy) {} + + [Equals.sym](that: unknown) { + return this === that + } + + [Hash.sym]() { + return Hash.randomCached(this) + } } export interface Suspend extends Eval {} -export class Suspend { +export class Suspend implements Equals { readonly _tag = "Suspend" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly f: Lazy>) {} + + [Equals.sym](that: unknown) { + return this === that + } + + [Hash.sym]() { + return Hash.randomCached(this) + } } export interface FlatMap extends Eval {} -export class FlatMap { +export class FlatMap implements Equals { readonly _tag = "FlatMap" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly value: EvalInternal, readonly cont: (a: A) => EvalInternal) {} + + [Equals.sym](that: unknown) { + return this === that + } + + [Hash.sym]() { + return Hash.randomCached(this) + } } export interface EvalF extends HKT { diff --git a/packages/stdlib/_src/service/Tag.ts b/packages/stdlib/_src/service/Tag.ts index 490a3d1e..80eb5aaf 100644 --- a/packages/stdlib/_src/service/Tag.ts +++ b/packages/stdlib/_src/service/Tag.ts @@ -14,6 +14,12 @@ export const Tag: TagOps = Object.assign( [Tag.sym]: identity, toEnv(value) { return Env(this, value) + }, + [Equals.sym](that) { + return this === that + }, + [Hash.sym]() { + return Hash.randomCached(this) } }), { @@ -25,7 +31,7 @@ export const Tag: TagOps = Object.assign( /** * @tsplus type Tag */ -export interface Tag { +export interface Tag extends Equals { readonly [Tag.sym]: (_: S) => S toEnv(value: S): Service.Env diff --git a/packages/stdlib/_src/structure/Equals.ts b/packages/stdlib/_src/structure/Equals.ts index 9217313d..959c191b 100644 --- a/packages/stdlib/_src/structure/Equals.ts +++ b/packages/stdlib/_src/structure/Equals.ts @@ -59,6 +59,15 @@ const protoMap = new Map boolean>([ [ Object.prototype, (a: object, b: object) => { + if ("_tag" in a) { + if ("_tag" in b) { + if (a["_tag"] !== b["_tag"]) { + return false + } + } else { + return false + } + } const keysA = Object.keys(a).sort() const keysB = Object.keys(b).sort() if (keysA.length !== keysB.length) {