feat: add a first generic method, square (#10)
All checks were successful
/ test (push) Successful in 10s
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:
parent
1a6890f458
commit
05ff078529
7 changed files with 34 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
11
src/generic/__test__/arithmetic.spec.js
Normal file
11
src/generic/__test__/arithmetic.spec.js
Normal 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
1
src/generic/all.js
Normal file
|
@ -0,0 +1 @@
|
|||
export * as arithmetic from './arithmetic.js'
|
8
src/generic/arithmetic.js
Normal file
8
src/generic/arithmetic.js
Normal 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
1
src/generics.js
Normal file
|
@ -0,0 +1 @@
|
|||
export * as generics from './generic/all.js'
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue