fix: Separate typed instance for each PocomathInstance (#15)
Also starts each PocomathInstance with no types at all, and uses the new situation to eliminate the need for a Complex "base case". Resolves #14. Resolves #13. Co-authored-by: Glen Whitney <glen@studioinfinity.org> Reviewed-on: #15
This commit is contained in:
parent
ed71b15969
commit
0069597a76
25 changed files with 120 additions and 74 deletions
20
src/complex/Types/Complex.mjs
Normal file
20
src/complex/Types/Complex.mjs
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Use a plain object with keys re and im for a complex; note the components
|
||||
* can be any type (for this proof-of-concept; in reality we'd want to
|
||||
* insist on some numeric or scalar supertype).
|
||||
*/
|
||||
export function isComplex(z) {
|
||||
return z && typeof z === 'object' && 're' in z && 'im' in z
|
||||
}
|
||||
|
||||
export const Types = {
|
||||
Complex: {
|
||||
test: isComplex,
|
||||
number: x => ({re: x, im: 0}),
|
||||
bigint: x => ({re: x, im: 0n})
|
||||
}
|
||||
}
|
||||
|
||||
/* test if an entity is Complex<number>, so to speak: */
|
||||
export function numComplex(z) {
|
||||
return isComplex(z) && typeof z.re === 'number' && typeof z.im === 'number'
|
||||
}
|
10
src/complex/add.mjs
Normal file
10
src/complex/add.mjs
Normal file
|
@ -0,0 +1,10 @@
|
|||
export {Types} from './Types/Complex.mjs'
|
||||
|
||||
export const add = {
|
||||
'...Complex': [['self'], ref => addends => {
|
||||
if (addends.length === 0) return {re:0, im:0}
|
||||
const seed = addends.shift()
|
||||
return addends.reduce((w,z) =>
|
||||
({re: ref.self(w.re, z.re), im: ref.self(w.im, z.im)}), seed)
|
||||
}]
|
||||
}
|
5
src/complex/all.mjs
Normal file
5
src/complex/all.mjs
Normal file
|
@ -0,0 +1,5 @@
|
|||
export {Types} from './Types/Complex.mjs'
|
||||
export {complex} from './complex.mjs'
|
||||
export {add} from './add.mjs'
|
||||
export {negate} from './negate.mjs'
|
||||
export {subtract} from '../generic/subtract.mjs'
|
11
src/complex/complex.mjs
Normal file
11
src/complex/complex.mjs
Normal file
|
@ -0,0 +1,11 @@
|
|||
export {Types} from './Types/Complex.mjs'
|
||||
|
||||
export const complex = {
|
||||
/* Very permissive for sake of proof-of-concept; would be better to
|
||||
* have a numeric/scalar type, e.g. by implementing subtypes in
|
||||
* typed-function
|
||||
*/
|
||||
'any, any': [[], (x, y) => ({re: x, im: y})],
|
||||
/* Take advantage of conversions in typed-function */
|
||||
Complex: [[], z => z]
|
||||
}
|
18
src/complex/extendToComplex.mjs
Normal file
18
src/complex/extendToComplex.mjs
Normal file
|
@ -0,0 +1,18 @@
|
|||
import * as complex from './complex.mjs'
|
||||
|
||||
/* Add all the complex implementations for functions already
|
||||
in the instance:
|
||||
*/
|
||||
|
||||
export default async function extendToComplex(pmath) {
|
||||
pmath.install(complex)
|
||||
for (const name in pmath._imps) {
|
||||
const modulePath = `./${name}.mjs`
|
||||
try {
|
||||
const mod = await import(modulePath)
|
||||
pmath.install(mod)
|
||||
} catch (err) {
|
||||
// Guess it wasn't a method available in complex; no worries
|
||||
}
|
||||
}
|
||||
}
|
7
src/complex/negate.mjs
Normal file
7
src/complex/negate.mjs
Normal file
|
@ -0,0 +1,7 @@
|
|||
export {Types} from './Types/Complex.mjs'
|
||||
|
||||
export const negate = {
|
||||
Complex: [['self'], ref => z => {
|
||||
return {re: ref.self(z.re), im: ref.self(z.im)}
|
||||
}]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue