feat: Return type annotations (#53)
Provides the infrastructure to allow annotating the return types of functions, and does so for essentially every operation in the system (the only known exceptions being add, multiply, etc., on arbitrarily many arguments). One main infrastructure enhancements are bounded template types, e.g. `T:number` being a template parameter where T can take on the type `number` or any subtype thereof. A main internal enhancement is that base template types are no longer added to the typed universe; rather, there is a secondary, "meta" typed universe where they live. The primary point/purpose of this change is then the necessary search order for implementations can be much better modeled by typed-function's search order, using the `onMismatch` facility to redirect the search from fully instantiated implementations to the generic catchall implementations for each template (these catchalls live in the meta universe). Numerous other small improvements and bugfixes were encountered along the way. Co-authored-by: Glen Whitney <glen@studioinfinity.org> Reviewed-on: #53
This commit is contained in:
parent
207ac4330b
commit
31add66f4c
80 changed files with 1502 additions and 606 deletions
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
if (config.predictable) return Returns('bigint', (n,d) => quot(n,d))
|
||||
return Returns('bigint|undefined', (n, d) => {
|
||||
const q = n/d
|
||||
if (q * d == n) return q
|
||||
return undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Returns from '../core/Returns.mjs'
|
||||
export * from './Types/bigint.mjs'
|
||||
|
||||
export const negate = {bigint: () => b => -b}
|
||||
export const negate = {bigint: () => Returns('bigint', b => -b)}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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<bigint>|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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue