From bc434c716335615f006d3a1235338c62950412fe Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Wed, 24 Aug 2022 20:59:30 -0400 Subject: [PATCH] feat(bigint): Specify return types for all methods --- src/bigint/absquare.mjs | 3 ++- src/bigint/add.mjs | 3 ++- src/bigint/compare.mjs | 4 +++- src/bigint/divide.mjs | 5 +++-- src/bigint/isZero.mjs | 3 ++- src/bigint/multiply.mjs | 3 ++- src/bigint/native.mjs | 4 ++-- src/bigint/one.mjs | 3 ++- src/bigint/quotient.mjs | 7 ++++--- src/bigint/roundquotient.mjs | 5 +++-- src/bigint/sign.mjs | 5 +++-- src/bigint/sqrt.mjs | 13 +++++++------ src/bigint/zero.mjs | 3 ++- src/generic/gcdType.mjs | 6 ++++-- src/generic/identity.mjs | 12 ++++++++++-- src/number/native.mjs | 4 ++-- test/_pocomath.mjs | 8 ++++++++ 17 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/bigint/absquare.mjs b/src/bigint/absquare.mjs index 4c2040a..587e8ec 100644 --- a/src/bigint/absquare.mjs +++ b/src/bigint/absquare.mjs @@ -1,6 +1,7 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' /* Absolute value squared */ export const absquare = { - bigint: ({'square(bigint)': sqb}) => b => sqb(b) + bigint: ({'square(bigint)': sqb}) => Returns('bigint', b => sqb(b)) } diff --git a/src/bigint/add.mjs b/src/bigint/add.mjs index 1cd296d..c4291ac 100644 --- a/src/bigint/add.mjs +++ b/src/bigint/add.mjs @@ -1,3 +1,4 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -export const add = {'bigint,bigint': () => (a,b) => a+b} +export const add = {'bigint,bigint': () => Returns('bigint', (a,b) => a+b)} diff --git a/src/bigint/compare.mjs b/src/bigint/compare.mjs index ab830ab..097dfca 100644 --- a/src/bigint/compare.mjs +++ b/src/bigint/compare.mjs @@ -1,5 +1,7 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' export const compare = { - 'bigint,bigint': () => (a,b) => a === b ? 0n : (a > b ? 1n : -1n) + 'bigint,bigint': () => Returns( + 'boolean', (a,b) => a === b ? 0n : (a > b ? 1n : -1n)) } diff --git a/src/bigint/divide.mjs b/src/bigint/divide.mjs index 4554457..028d3e6 100644 --- a/src/bigint/divide.mjs +++ b/src/bigint/divide.mjs @@ -1,12 +1,13 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' export const divide = { 'bigint,bigint': ({config, 'quotient(bigint,bigint)': quot}) => { if (config.predictable) return quot - return (n, d) => { + return Returns('bigint|undefined', (n, d) => { const q = n/d if (q * d == n) return q return undefined - } + }) } } diff --git a/src/bigint/isZero.mjs b/src/bigint/isZero.mjs index 0efa71c..02aca57 100644 --- a/src/bigint/isZero.mjs +++ b/src/bigint/isZero.mjs @@ -1,3 +1,4 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -export const isZero = {bigint: () => b => b === 0n} +export const isZero = {bigint: () => Returns('boolean', b => b === 0n)} diff --git a/src/bigint/multiply.mjs b/src/bigint/multiply.mjs index e19959e..e80cee0 100644 --- a/src/bigint/multiply.mjs +++ b/src/bigint/multiply.mjs @@ -1,3 +1,4 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -export const multiply = {'bigint,bigint': () => (a,b) => a*b} +export const multiply = {'bigint,bigint': () => Returns('bigint', (a,b) => a*b)} diff --git a/src/bigint/native.mjs b/src/bigint/native.mjs index 6cc76d4..b387615 100644 --- a/src/bigint/native.mjs +++ b/src/bigint/native.mjs @@ -1,12 +1,12 @@ import gcdType from '../generic/gcdType.mjs' -import {identity} from '../generic/identity.mjs' +import {identityType} from '../generic/identity.mjs' export * from './Types/bigint.mjs' export {absquare} from './absquare.mjs' export {add} from './add.mjs' export {compare} from './compare.mjs' -export const conjugate = {bigint: () => identity} +export const conjugate = {bigint: identityType('bigint')} export {divide} from './divide.mjs' export const gcd = gcdType('bigint') export {isZero} from './isZero.mjs' diff --git a/src/bigint/one.mjs b/src/bigint/one.mjs index f548a65..8e8a7f2 100644 --- a/src/bigint/one.mjs +++ b/src/bigint/one.mjs @@ -1,3 +1,4 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -export const one = {bigint: () => () => 1n} +export const one = {bigint: () => Returns('bigint', () => 1n)} diff --git a/src/bigint/quotient.mjs b/src/bigint/quotient.mjs index 589adc3..c1a086a 100644 --- a/src/bigint/quotient.mjs +++ b/src/bigint/quotient.mjs @@ -1,13 +1,14 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -/* Returns the best integer approximation to n/d */ +/* Returns the floor integer approximation to n/d */ export const quotient = { - 'bigint,bigint': ({'sign(bigint)': sgn}) => (n, d) => { + 'bigint,bigint': ({'sign(bigint)': sgn}) => Returns('bigint', (n, d) => { const dSgn = sgn(d) if (dSgn === 0n) return 0n if (sgn(n) === dSgn) return n/d const quot = n/d if (quot * d == n) return quot return quot - 1n - } + }) } diff --git a/src/bigint/roundquotient.mjs b/src/bigint/roundquotient.mjs index c6763a2..57fb941 100644 --- a/src/bigint/roundquotient.mjs +++ b/src/bigint/roundquotient.mjs @@ -1,8 +1,9 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' /* Returns the closest integer approximation to n/d */ export const roundquotient = { - 'bigint,bigint': ({'sign(bigint)': sgn}) => (n, d) => { + 'bigint,bigint': ({'sign(bigint)': sgn}) => Returns('bigint', (n, d) => { const dSgn = sgn(d) if (dSgn === 0n) return 0n const candidate = n/d @@ -11,5 +12,5 @@ export const roundquotient = { if (2n * rem > absd) return candidate + dSgn if (-2n * rem >= absd) return candidate - dSgn return candidate - } + }) } diff --git a/src/bigint/sign.mjs b/src/bigint/sign.mjs index af48e05..c811df2 100644 --- a/src/bigint/sign.mjs +++ b/src/bigint/sign.mjs @@ -1,9 +1,10 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' export const sign = { - bigint: () => b => { + bigint: () => Returns('bigint', b => { if (b === 0n) return 0n if (b > 0n) return 1n return -1n - } + }) } diff --git a/src/bigint/sqrt.mjs b/src/bigint/sqrt.mjs index 4d34513..01ef0b0 100644 --- a/src/bigint/sqrt.mjs +++ b/src/bigint/sqrt.mjs @@ -1,5 +1,6 @@ -export * from './Types/bigint.mjs' +import Returns from '../core/Returns.mjs' import isqrt from 'bigint-isqrt' +export * from './Types/bigint.mjs' export const sqrt = { bigint: ({ @@ -11,18 +12,18 @@ export const sqrt = { // Don't just return the constant isqrt here because the object // gets decorated with info that might need to be different // for different PocomathInstancss - return b => isqrt(b) + return Returns('bigint', b => isqrt(b)) } if (!cplx) { - return b => { + return Returns('bigint|undefined', b => { if (b >= 0n) { const trial = isqrt(b) if (trial * trial === b) return trial } return undefined - } + }) } - return b => { + return Returns('bigint|Complex|undefined', b => { if (b === undefined) return undefined let real = true if (b < 0n) { @@ -33,6 +34,6 @@ export const sqrt = { if (trial * trial !== b) return undefined if (real) return trial return cplx(0n, trial) - } + }) } } diff --git a/src/bigint/zero.mjs b/src/bigint/zero.mjs index 0c63a1a..e9fe83b 100644 --- a/src/bigint/zero.mjs +++ b/src/bigint/zero.mjs @@ -1,3 +1,4 @@ +import Returns from '../core/Returns.mjs' export * from './Types/bigint.mjs' -export const zero = {bigint: () => () => 0n} +export const zero = {bigint: () => Returns('bigint', () => 0n)} diff --git a/src/generic/gcdType.mjs b/src/generic/gcdType.mjs index 1ca16ab..ee86b50 100644 --- a/src/generic/gcdType.mjs +++ b/src/generic/gcdType.mjs @@ -1,3 +1,5 @@ +import Returns from '../core/Returns.mjs' + /* Note we do not use a template here so that we can explicitly control * which types this is instantiated for, namely the "integer" types, and * not simply allow Pocomath to generate instances for any type it encounters. @@ -7,14 +9,14 @@ export default function(type) { const producer = refs => { const modder = refs[`mod(${type},${type})`] const zeroTester = refs[`isZero(${type})`] - return (a,b) => { + return Returns(type, (a,b) => { while (!zeroTester(b)) { const r = modder(a,b) a = b b = r } return a - } + }) } const retval = {} retval[`${type},${type}`] = producer diff --git a/src/generic/identity.mjs b/src/generic/identity.mjs index 2422d2f..fb3853e 100644 --- a/src/generic/identity.mjs +++ b/src/generic/identity.mjs @@ -1,3 +1,11 @@ -export function identity(x) { - return x +import Returns from '../core/Returns.mjs' + +export function identityType(type) { + return () => Returns(type, x => x) } + +export function identitySubTypes(type) { + return ({T}) => Returns(T, x => x) +} + +export const identity = {T: ({T}) => Returns(T, x => x)} diff --git a/src/number/native.mjs b/src/number/native.mjs index 6746408..fcebecc 100644 --- a/src/number/native.mjs +++ b/src/number/native.mjs @@ -1,5 +1,5 @@ import gcdType from '../generic/gcdType.mjs' -import {identity} from '../generic/identity.mjs' +import {identitySubTypes} from '../generic/identity.mjs' export * from './Types/number.mjs' @@ -7,7 +7,7 @@ export {abs} from './abs.mjs' export {absquare} from './absquare.mjs' export {add} from './add.mjs' export {compare} from './compare.mjs' -export const conjugate = {number: () => identity} +export const conjugate = {'T:number': identitySubTypes('number')} export const gcd = gcdType('NumInt') export {invert} from './invert.mjs' export {isZero} from './isZero.mjs' diff --git a/test/_pocomath.mjs b/test/_pocomath.mjs index eb0481b..b49efb6 100644 --- a/test/_pocomath.mjs +++ b/test/_pocomath.mjs @@ -38,6 +38,14 @@ describe('The default full pocomath instance "math"', () => { math.returnTypeOf('chain', 'bigint'), 'Chain') assert.strictEqual( math.returnTypeOf('returnTypeOf', 'string,string'), 'string') + assert.strictEqual( + math.returnTypeOf('conjugate', 'bigint'), 'bigint') + assert.strictEqual( + math.returnTypeOf('gcd', 'bigint,bigint'), 'bigint') + math.identity(math.fraction(3,5)) // TODO: ditto + assert.strictEqual(math.returnTypeOf('identity', 'Fraction'), 'Fraction') + assert.strictEqual( + math.returnTypeOf('quotient', 'bigint,bigint'), 'bigint') }) it('can subtract numbers', () => {