feat(floor): Provide example of op-centric organization #42
@ -1,5 +1,6 @@
|
||||
import PocomathInstance from '../core/PocomathInstance.mjs'
|
||||
import * as bigints from './native.mjs'
|
||||
import * as generic from '../generic/all.mjs'
|
||||
import * as floor from '../ops/floor.mjs'
|
||||
|
||||
export default PocomathInstance.merge('bigint', bigints, generic)
|
||||
export default PocomathInstance.merge('bigint', bigints, generic, floor)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import PocomathInstance from '../core/PocomathInstance.mjs'
|
||||
import * as complexes from './native.mjs'
|
||||
import * as generic from '../generic/arithmetic.mjs'
|
||||
import * as floor from '../ops/floor.mjs'
|
||||
|
||||
export default PocomathInstance.merge('complex', complexes, generic)
|
||||
export default PocomathInstance.merge('complex', complexes, generic, floor)
|
||||
|
@ -471,6 +471,7 @@ export default class PocomathInstance {
|
||||
}
|
||||
|
||||
for (const instType of instantiationSet) {
|
||||
if (!(instType in this.Types)) continue
|
||||
if (this.Types[instType] === anySpec) continue
|
||||
const signature =
|
||||
substituteInSig(trimSignature, theTemplateParam, instType)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import PocomathInstance from '../core/PocomathInstance.mjs'
|
||||
import * as numbers from './native.mjs'
|
||||
import * as generic from '../generic/all.mjs'
|
||||
import * as floor from '../ops/floor.mjs'
|
||||
|
||||
export default PocomathInstance.merge('number', numbers, generic)
|
||||
export default PocomathInstance.merge('number', numbers, generic, floor)
|
||||
|
||||
|
25
src/ops/floor.mjs
Normal file
25
src/ops/floor.mjs
Normal file
@ -0,0 +1,25 @@
|
||||
import {Complex} from '../complex/Types/Complex.mjs'
|
||||
|
||||
/* Note we don't **export** any types here, so that only the options
|
||||
* below that correspond to types that have been installed are activated.
|
||||
*/
|
||||
|
||||
export const floor = {
|
||||
bigint: () => x => x,
|
||||
NumInt: () => x => x, // Because Pocomath isn't part of typed-function, or
|
||||
GaussianInteger: () => x => x, // at least have access to the real
|
||||
// typed-function parse, we unfortunately can't coalesce these into one
|
||||
// entry with type `bigint|NumInt|GaussianInteger` because they couldn't
|
||||
// be separately activated then
|
||||
|
||||
number: ({'equal(number,number)': eq}) => n => {
|
||||
if (eq(n, Math.round(n))) return Math.round(n)
|
||||
return Math.floor(n)
|
||||
},
|
||||
|
||||
Complex: Complex.promoteUnary.Complex,
|
||||
|
||||
// OK to include a type totally not in Pocomath yet, it'll never be
|
||||
// activated.
|
||||
Fraction: ({quotient}) => f => quotient(f.n, f.d),
|
||||
}
|
@ -4,7 +4,9 @@ import * as numbers from './number/native.mjs'
|
||||
import * as bigints from './bigint/native.mjs'
|
||||
import * as complex from './complex/native.mjs'
|
||||
import * as generic from './generic/all.mjs'
|
||||
import * as floor from './ops/floor.mjs'
|
||||
|
||||
const math = PocomathInstance.merge('math', numbers, bigints, complex, generic)
|
||||
const math = PocomathInstance.merge(
|
||||
'math', numbers, bigints, complex, generic, floor)
|
||||
|
||||
export default math
|
||||
|
@ -3,12 +3,12 @@ import PocomathInstance from '../src/core/PocomathInstance.mjs'
|
||||
import math from '../src/pocomath.mjs'
|
||||
|
||||
describe('The default full pocomath instance "math"', () => {
|
||||
it('has no undefined types', () => {
|
||||
it('has no unexpected undefined types', () => {
|
||||
const undef = math.undefinedTypes()
|
||||
if (undef.length) {
|
||||
console.log('Probable typo: found undefined types', undef)
|
||||
console.log('NOTE: Found undefined types', undef)
|
||||
}
|
||||
assert.strictEqual(undef.length, 0)
|
||||
assert.strictEqual(undef.length, 1) // Mentioning 'Fraction' but not using
|
||||
})
|
||||
|
||||
it('has a built-in typeOf operator', () => {
|
||||
|
@ -64,4 +64,8 @@ describe('bigint', () => {
|
||||
assert.strictEqual(math.lcm(0n, 0n), 0n)
|
||||
})
|
||||
|
||||
it('allows floor as a no-op', () => {
|
||||
assert.strictEqual(math.floor(-333n), -333n)
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -51,4 +51,12 @@ describe('complex', () => {
|
||||
math.complex(4n, 5n))
|
||||
})
|
||||
|
||||
it('computes floor', () => {
|
||||
assert.deepStrictEqual(
|
||||
math.floor(math.complex(19, 22.7)),
|
||||
math.complex(19, 22))
|
||||
const gi = math.complex(-1n, 1n)
|
||||
assert.strictEqual(math.floor(gi), gi) // literally a no-op
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -38,12 +38,20 @@ describe('A custom instance', () => {
|
||||
const pm = new PocomathInstance('piecemeal')
|
||||
pm.install(numbers)
|
||||
assert.strictEqual(pm.subtract(5, 10), -5)
|
||||
assert.strictEqual(pm.floor(3.7), 3)
|
||||
assert.throws(() => pm.floor(10n), TypeError)
|
||||
pm.install(complexAdd)
|
||||
pm.install(complexNegate)
|
||||
pm.install(complexComplex)
|
||||
// Should be enough to allow complex subtraction, as subtract is generic:
|
||||
assert.deepStrictEqual(
|
||||
pm.subtract({re:5, im:0}, {re:10, im:1}), {re:-5, im: -1})
|
||||
pm.subtract(pm.complex(5, 0), pm.complex(10, 1)),
|
||||
math.complex(-5, -1))
|
||||
// And now floor has been activated for Complex as well, since the type
|
||||
// is present
|
||||
assert.deepStrictEqual(
|
||||
pm.floor(math.complex(1.9, 0)),
|
||||
math.complex(1))
|
||||
})
|
||||
|
||||
it("can defer definition of (even used) types", () => {
|
||||
|
@ -37,4 +37,10 @@ describe('number', () => {
|
||||
assert.ok(math.largerEq(12.5, math.divide(25,2)))
|
||||
})
|
||||
|
||||
it('Computes floor', () => {
|
||||
assert.strictEqual(math.floor(7), 7)
|
||||
assert.strictEqual(math.floor(6.99), 6)
|
||||
assert.strictEqual(math.floor(1-1e-13), 1)
|
||||
})
|
||||
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user