feat: Implement subtypes
This should eventually be moved into typed-function itself, but for now it can be implemented on top of the existing typed-function. Uses subtypes to define (and error-check) gcd and lcm, which are only defined for integer arguments. Resolves #36.
This commit is contained in:
parent
4d38f4161c
commit
c429c19dfe
35 changed files with 294 additions and 43 deletions
|
@ -1,7 +1,10 @@
|
|||
export * from './Types/generic.mjs'
|
||||
|
||||
export {lcm} from './lcm.mjs'
|
||||
export {mod} from './mod.mjs'
|
||||
export {multiply} from './multiply.mjs'
|
||||
export {divide} from './divide.mjs'
|
||||
export {sign} from './sign.mjs'
|
||||
export {sqrt} from './sqrt.mjs'
|
||||
export {square} from './square.mjs'
|
||||
export {subtract} from './subtract.mjs'
|
||||
|
|
18
src/generic/gcdType.mjs
Normal file
18
src/generic/gcdType.mjs
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Returns a object that defines the gcd for the given type */
|
||||
export default function(type) {
|
||||
const producer = refs => {
|
||||
const modder = refs[`mod(${type},${type})`]
|
||||
const zeroTester = refs[`isZero(${type})`]
|
||||
return (a,b) => {
|
||||
while (!zeroTester(b)) {
|
||||
const r = modder(a,b)
|
||||
a = b
|
||||
b = r
|
||||
}
|
||||
return a
|
||||
}
|
||||
}
|
||||
const retval = {}
|
||||
retval[`${type},${type}`] = producer
|
||||
return retval
|
||||
}
|
6
src/generic/lcm.mjs
Normal file
6
src/generic/lcm.mjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
export const lcm = {
|
||||
'any,any': ({
|
||||
multiply,
|
||||
quotient,
|
||||
gcd}) => (a,b) => multiply(quotient(a, gcd(a,b)), b)
|
||||
}
|
6
src/generic/mod.mjs
Normal file
6
src/generic/mod.mjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
export const mod = {
|
||||
'any,any': ({
|
||||
subtract,
|
||||
multiply,
|
||||
quotient}) => (a,m) => subtract(a, multiply(m, quotient(a,m)))
|
||||
}
|
|
@ -4,9 +4,9 @@ export const multiply = {
|
|||
'undefined': () => u => u,
|
||||
'undefined,...any': () => (u, rest) => u,
|
||||
'any,undefined': () => (x, u) => u,
|
||||
'any,undefined,...any': () => (x, u, rest) => u,
|
||||
'any,any,undefined': () => (x, y, u) => u,
|
||||
'any,any,undefined,...any': () => (x, y, u, rest) => u
|
||||
// Bit of a hack since this should go on indefinitely...
|
||||
'any,any,...any': ({self}) => (a,b,rest) => {
|
||||
const later = [b, ...rest]
|
||||
return later.reduce((x,y) => self(x,y), a)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3
src/generic/square.mjs
Normal file
3
src/generic/square.mjs
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const square = {
|
||||
any: ({multiply}) => x => multiply(x,x)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue