feat: add a first generic method, square (#10)
All checks were successful
/ test (push) Successful in 10s

Resolves #2.

Reviewed-on: #10
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Co-committed-by: Glen Whitney <glen@studioinfinity.org>
This commit is contained in:
Glen Whitney 2025-04-08 23:25:01 +00:00 committed by Glen Whitney
parent 1a6890f458
commit 05ff078529
7 changed files with 34 additions and 4 deletions

View file

@ -151,7 +151,7 @@ export class TypeDispatcher {
throw new ReferenceError(`no method or value for key '${key}'`)
}
if (this.resolve._genDepsOf?.length) _addToDeps(key, types)
if (this.resolve._genDepsOf?.length) this._addToDeps(key, types)
const behave = this._behaviors[key]
if (behave.has(types)) return behave.get(types)
@ -192,8 +192,6 @@ export class TypeDispatcher {
try {
theBehavior = item(DependencyRecorder(this, [], this), template)
} catch {
// Didn't work as a factory, so guess we were wrong; just
// make this entity the behavior:
behave.set(types, item)
return item
} finally {
@ -201,6 +199,7 @@ export class TypeDispatcher {
}
if (typeof theBehavior === 'function'
&& theBehavior.length
&& Array.isArray(template)
&& template.some(elt => Array.isArray(elt))
) {
// have to wrap the behavior to collect the actual arguments

View file

@ -1,9 +1,11 @@
import assert from 'assert'
import {TypeDispatcher} from '../TypeDispatcher.js'
import {numbers} from '../../numbers.js'
import {generics} from '../../generics.js'
import {onType} from "#core/helpers.js"
import {Any} from "#core/TypePatterns.js"
import {Returns} from "#core/Type.js"
import {plain} from "#number/helpers.js"
describe('TypeDispatcher', () => {
it('can build in stages', () => {
@ -38,4 +40,11 @@ describe('TypeDispatcher', () => {
incremental.add.resolve([Undefined, Number]).returns,
Number)
})
it('changes methods when their dependencies change', () => {
const gnmath = new TypeDispatcher(generics, numbers)
assert.strictEqual(gnmath.square(-2.5), 6.25)
// change multiplication of number to floor its first argument (?!)
gnmath.merge({multiply: plain((a,b) => Math.floor(a) * b)})
assert.strictEqual(gnmath.square(-2.5), 7.5)
})
})

View file

@ -0,0 +1,11 @@
import assert from 'assert'
import math from '#nanomath'
describe('generic arithmetic', () => {
it('squares anything', () => {
assert.strictEqual(math.square(7), 49)
assert.strictEqual(
math.square.resolve([math.types.Number]).returns,
math.types.Number)
})
})

1
src/generic/all.js Normal file
View file

@ -0,0 +1 @@
export * as arithmetic from './arithmetic.js'

View file

@ -0,0 +1,8 @@
import {onType} from '#core/helpers.js'
import {Returns} from '#core/Type.js'
import {Any} from '#core/TypePatterns.js'
export const square = onType(Any, (math, T) => {
const mult = math.multiply.resolve([T, T])
return Returns(mult.returns, a => mult(a, a))
})

1
src/generics.js Normal file
View file

@ -0,0 +1 @@
export * as generics from './generic/all.js'

View file

@ -1,6 +1,7 @@
import {generics} from './generics.js'
import {numbers} from './numbers.js'
import {TypeDispatcher} from '#core/TypeDispatcher.js'
const math = new TypeDispatcher(numbers)
const math = new TypeDispatcher(generics, numbers)
export default math