feat: Add vector deepEqual

This commit is contained in:
Glen Whitney 2025-04-28 21:25:02 -07:00
parent 3b882f3d53
commit 7b799f7183
6 changed files with 41 additions and 1 deletions

View file

@ -39,6 +39,9 @@ export const equal = match([Any, Any], (math, [T, U]) => {
// now that we have `equal` and `exceeds`, pretty much everything else should
// be easy:
export const deepEqual = match(
Passthru, (math, types, strategy) => math.equal.resolve(types, strategy))
export const compare = match([Any, Any], (math, [T, U]) => {
const eq = math.equal.resolve([T, U])
const gt = math.exceeds.resolve([T, U])

View file

@ -0,0 +1,16 @@
import assert from 'assert'
import math from '#nanomath'
describe('Vector relational functions', () => {
it('can test two vectors for deep equality', () => {
const dEq = math.deepEqual
const pyth = [3, 4, 5]
assert.strictEqual(dEq(pyth, [3, 4, 5]), true)
assert.strictEqual(dEq(pyth, [3, 4, 6]), false)
assert.strictEqual(dEq(pyth, [3, 4, [5]]), false)
assert.strictEqual(dEq(3, 3 + 1e-13), true)
assert.strictEqual(dEq(pyth, [3+1e-13, 4-1e-13, 5]), true)
assert.strictEqual(dEq([pyth, pyth], [pyth, [3, 4, 5]]), true)
assert.strictEqual(dEq([3], 3), false)
})
})

View file

@ -1,4 +1,5 @@
export * as typeDefinition from './Vector.js'
export * as relational from './relational.js'
export * as type from './type.js'
export * as utilities from './utils.js'

20
src/vector/relational.js Normal file
View file

@ -0,0 +1,20 @@
import {Vector} from './Vector.js'
import {NotAType, Returns} from '#core/Type.js'
import {Any, match} from '#core/TypePatterns.js'
import {BooleanT} from '#boolean/BooleanT.js'
export const deepEqual = [
match([Vector, Any], Returns(BooleanT, () => false)),
match([Any, Vector], Returns(BooleanT, () => false)),
match([Vector, Vector], (math, [V, W]) => {
if (V.Component === NotAType || W.Component === NotAType) {
return Returns(BooleanT, (v, w) => v === w
|| (v.length === w.length
&& v.every((e, i) => math.deepEqual(e, w[i]))))
}
const compDeep = math.deepEqual.resolve([V.Component, W.Component])
return Returns(BooleanT, (v,w) => v === w
|| (v.length === w.length
&& v.every((e, i) => compDeep(e, w[i]))))
})
]

View file

@ -2,7 +2,7 @@ import {Vector} from './Vector.js'
import {NotAType, Returns} from '#core/Type.js'
import {Any, Multiple, match} from '#core/TypePatterns.js'
export const vector = match(Multiple(Any), (math, TV) => {
export const vector = match(Multiple(Any), (math, [TV]) => {
if (!TV.length) return Returns(Vector(NotAType), () => [])
let CompType = TV[0]
if (TV.some(T => T !== CompType)) CompType = NotAType