refactor: Convert resolution to two-tier system
Typed-function's sort order/matching algorithm was interfering with template resolution. This commit solves the difficulty by moving the "catchall" implementations that implement generation of new template instances into a separate "fallback" typed-function universe, so that Pocomath can control exactly when that is searched. Removes a couple of the matching anomalies already noted in the tests. Also extends return types to somewhat more functions.
This commit is contained in:
parent
a2f76a55b8
commit
de42c22ab4
13 changed files with 428 additions and 278 deletions
|
@ -46,6 +46,9 @@ describe('The default full pocomath instance "math"', () => {
|
|||
assert.strictEqual(math.returnTypeOf('identity', 'Fraction'), 'Fraction')
|
||||
assert.strictEqual(
|
||||
math.returnTypeOf('quotient', 'bigint,bigint'), 'bigint')
|
||||
math.abs(math.complex(2,1)) //TODO: ditto
|
||||
assert.strictEqual(
|
||||
math.returnTypeOf('abs','Complex<NumInt>'), 'number')
|
||||
})
|
||||
|
||||
it('can subtract numbers', () => {
|
||||
|
|
|
@ -39,8 +39,8 @@ describe('complex', () => {
|
|||
})
|
||||
|
||||
it('checks for equality', () => {
|
||||
assert.ok(math.equal(math.complex(3,0), 3))
|
||||
assert.ok(math.equal(math.complex(3,2), math.complex(3, 2)))
|
||||
assert.ok(math.equal(math.complex(3, 0), 3))
|
||||
assert.ok(math.equal(math.complex(3, 2), math.complex(3, 2)))
|
||||
assert.ok(!(math.equal(math.complex(45n, 3n), math.complex(45n, -3n))))
|
||||
assert.ok(!(math.equal(math.complex(45n, 3n), 45n)))
|
||||
})
|
||||
|
|
|
@ -135,13 +135,8 @@ describe('A custom instance', () => {
|
|||
assert.strictEqual(
|
||||
inst.typeMerge(3, inst.complex(4.5,2.1)),
|
||||
'Merge to Complex<number>')
|
||||
// The following is the current behavior, since 3 converts to 3+0i
|
||||
// which is technically the same Complex type as 3n+0ni.
|
||||
// This should clear up when Complex is templatized
|
||||
assert.strictEqual(inst.typeMerge(3, inst.complex(3n)), 'Merge to Complex')
|
||||
// But types that truly cannot be merged should throw a TypeError
|
||||
// Should add a variation of this with a more usual type once there is
|
||||
// one not interconvertible with others...
|
||||
assert.throws(
|
||||
() => inst.typeMerge(3, inst.complex(3n)), TypeError)
|
||||
inst.install(genericSubtract)
|
||||
assert.throws(() => inst.typeMerge(3, undefined), TypeError)
|
||||
})
|
||||
|
|
|
@ -8,14 +8,12 @@ describe('tuple', () => {
|
|||
|
||||
it('does not allow unification by converting consecutive arguments', () => {
|
||||
assert.throws(() => math.tuple(3, 5.2, 2n), /TypeError.*unif/)
|
||||
// Hence, the order matters in a slightly unfortunate way,
|
||||
// but I think being a little ragged in these edge cases is OK:
|
||||
assert.throws(
|
||||
() => math.tuple(3, 2n, math.complex(5.2)),
|
||||
/TypeError.*unif/)
|
||||
assert.deepStrictEqual(
|
||||
math.tuple(3, math.complex(2n), 5.2),
|
||||
{elts: [math.complex(3), math.complex(2n), math.complex(5.2)]})
|
||||
assert.throws(
|
||||
() => math.tuple(3, math.complex(2n), 5.2),
|
||||
/TypeError.*unif/)
|
||||
})
|
||||
|
||||
it('can be tested for zero and equality', () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue