From 7d150e28608123647d0bdcf8f0cffcff13c7edd5 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Mon, 28 Apr 2025 16:02:26 -0700 Subject: [PATCH] feat: Add vector constructor/converter --- src/vector/Vector.js | 5 +++++ src/vector/__test__/type.js | 16 ++++++++++++++++ src/vector/all.js | 2 ++ src/vector/type.js | 12 ++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 src/vector/__test__/type.js create mode 100644 src/vector/type.js diff --git a/src/vector/Vector.js b/src/vector/Vector.js index 0f82e4f..1fbf3f2 100644 --- a/src/vector/Vector.js +++ b/src/vector/Vector.js @@ -22,6 +22,10 @@ export const Vector = new Type(isVector, { specializesTo: VT => this.specializesTo(VT) && CompType.specializesTo(VT.Component), refine: (v, typer) => { + if (!v.length) { + throw new RangeError( + `no way to refine ${typeName} on an empty vector`) + } const eltTypes = v.map(elt => CompType.refine(elt, typer)) const newCompType = eltTypes[0] if (eltTypes.some(T => T !== newCompType)) { @@ -35,6 +39,7 @@ export const Vector = new Type(isVector, { }, specializesTo: VT => VT.vector, refine(v, typer) { + if (!v.length) return this.specialize(NotAType) // what else could we do? const eltTypes = v.map(elt => typer(elt)) let compType = eltTypes[0] if (eltTypes.some(T => T !== compType)) compType = NotAType diff --git a/src/vector/__test__/type.js b/src/vector/__test__/type.js new file mode 100644 index 0000000..43dc101 --- /dev/null +++ b/src/vector/__test__/type.js @@ -0,0 +1,16 @@ +import assert from 'assert' +import {NotAType} from '#core/Type.js' +import math from '#nanomath' + +describe('Vector type functions', () => { + it('can construct a vector', () => { + const vec = math.vector + const {BooleanT, NumberT, Vector} = math.types + assert.deepStrictEqual(vec(3, 4, 5), [3, 4, 5]) + assert.strictEqual( + vec.resolve([NumberT, NumberT, NumberT]).returns, Vector(NumberT)) + assert.deepStrictEqual(vec(3, true), [3, true]) + assert.strictEqual( + vec.resolve([NumberT, BooleanT]).returns, Vector(NotAType)) + }) +}) diff --git a/src/vector/all.js b/src/vector/all.js index b5fe798..81a3f9d 100644 --- a/src/vector/all.js +++ b/src/vector/all.js @@ -1 +1,3 @@ export * as typeDefinition from './Vector.js' +export * as type from './type.js' + diff --git a/src/vector/type.js b/src/vector/type.js new file mode 100644 index 0000000..d826372 --- /dev/null +++ b/src/vector/type.js @@ -0,0 +1,12 @@ +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) => { + if (!TV.length) return Returns(Vector(NotAType), () => []) + let CompType = TV[0] + if (TV.some(T => T !== CompType)) CompType = NotAType + return Returns(Vector(CompType), v => v) +}) + +