feat: Template operations (#41)

Relational functions are added using templates, and existing generic functions are made more strict with them. Also a new built-in typeOf function is added, that automatically updates itself.

Resolves #34.

Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #41
This commit is contained in:
Glen Whitney 2022-08-01 10:09:32 +00:00
parent 2609310b8e
commit fe54bc6004
29 changed files with 480 additions and 119 deletions

View file

@ -1,10 +1,22 @@
export * from './Types/Complex.mjs'
export const add = {
'...Complex': ({self}) => addends => {
if (addends.length === 0) return {re:0, im:0}
const seed = addends.shift()
return addends.reduce(
(w,z) => ({re: self(w.re, z.re), im: self(w.im, z.im)}), seed)
}
/* Relying on conversions for both complex + number and complex + bigint
* leads to an infinite loop when adding a number and a bigint, since they
* both convert to Complex.
*/
'Complex,number': ({
'self(number,number)': addNum,
'complex(any,any)': cplx
}) => (z,x) => cplx(addNum(z.re, x), z.im),
'Complex,bigint': ({
'self(bigint,bigint)': addBigInt,
'complex(any,any)': cplx
}) => (z,x) => cplx(addBigInt(z.re, x), z.im),
'Complex,Complex': ({
self,
'complex(any,any)': cplx
}) => (w,z) => cplx(self(w.re, z.re), self(w.im, z.im))
}

19
src/complex/equal.mjs Normal file
View file

@ -0,0 +1,19 @@
export * from './Types/Complex.mjs'
export const equal = {
'Complex,number': ({
'isZero(number)': isZ,
'self(number,number)': eqNum
}) => (z, x) => eqNum(z.re, x) && isZ(z.im),
'Complex,bigint': ({
'isZero(bigint)': isZ,
'self(bigint,bigint)': eqBigInt
}) => (z, b) => eqBigInt(z.re, b) && isZ(z.im),
'Complex,Complex': ({self}) => (w,z) => self(w.re, z.re) && self(w.im, z.im),
'GaussianInteger,GaussianInteger': ({
'self(bigint,bigint)': eq
}) => (a,b) => eq(a.re, b.re) && eq(a.im, b.im)
}

View file

@ -7,6 +7,7 @@ export {absquare} from './absquare.mjs'
export {add} from './add.mjs'
export {conjugate} from './conjugate.mjs'
export {complex} from './complex.mjs'
export {equal} from './equal.mjs'
export {gcd} from './gcd.mjs'
export {invert} from './invert.mjs'
export {isZero} from './isZero.mjs'

View file

@ -3,7 +3,7 @@ export * from './Types/Complex.mjs'
export const sqrt = {
Complex: ({
config,
zero,
isZero,
sign,
one,
add,
@ -16,11 +16,8 @@ export const sqrt = {
}) => {
if (config.predictable) {
return z => {
const imZero = zero(z.im)
const imSign = sign(z.im)
const reOne = one(z.re)
const reSign = sign(z.re)
if (imSign === imZero && reSign === reOne) return complex(self(z.re))
if (isZero(z.im) && sign(z.re) === reOne) return complex(self(z.re))
const reTwo = add(reOne, reOne)
return complex(
multiply(sign(z.im), self(divide(add(abs(z),z.re), reTwo))),
@ -29,11 +26,8 @@ export const sqrt = {
}
}
return z => {
const imZero = zero(z.im)
const imSign = sign(z.im)
const reOne = one(z.re)
const reSign = sign(z.re)
if (imSign === imZero && reSign === reOne) return self(z.re)
if (isZero(z.im) && sign(z.re) === reOne) return self(z.re)
const reTwo = add(reOne, reOne)
return complex(
multiply(sign(z.im), self(divide(add(abs(z),z.re), reTwo))),