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:
parent
2609310b8e
commit
fe54bc6004
29 changed files with 480 additions and 119 deletions
|
@ -1 +1,2 @@
|
|||
export * from './arithmetic.mjs'
|
||||
export * from './relational.mjs'
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import {reducingOperation} from './reducingOperation.mjs'
|
||||
|
||||
export * from './Types/generic.mjs'
|
||||
|
||||
export const add = reducingOperation
|
||||
export {lcm} from './lcm.mjs'
|
||||
export {mod} from './mod.mjs'
|
||||
export {multiply} from './multiply.mjs'
|
||||
export const multiply = reducingOperation
|
||||
export {divide} from './divide.mjs'
|
||||
export {sign} from './sign.mjs'
|
||||
export {sqrt} from './sqrt.mjs'
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
export const divide = {
|
||||
'any,any': ({multiply, invert}) => (x, y) => multiply(x, invert(y))
|
||||
'T,T': ({
|
||||
'multiply(T,T)': multT,
|
||||
'invert(T)': invT
|
||||
}) => (x, y) => multT(x, invT(y))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* 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.
|
||||
*/
|
||||
/* Returns a object that defines the gcd for the given type */
|
||||
export default function(type) {
|
||||
const producer = refs => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export const lcm = {
|
||||
'any,any': ({
|
||||
multiply,
|
||||
quotient,
|
||||
gcd}) => (a,b) => multiply(quotient(a, gcd(a,b)), b)
|
||||
'T,T': ({
|
||||
'multiply(T,T)': multT,
|
||||
'quotient(T,T)': quotT,
|
||||
'gcd(T,T)': gcdT
|
||||
}) => (a,b) => multT(quotT(a, gcdT(a,b)), b)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export const mod = {
|
||||
'any,any': ({
|
||||
subtract,
|
||||
multiply,
|
||||
quotient}) => (a,m) => subtract(a, multiply(m, quotient(a,m)))
|
||||
'T,T': ({
|
||||
'subtract(T,T)': subT,
|
||||
'multiply(T,T)': multT,
|
||||
'quotient(T,T)': quotT
|
||||
}) => (a,m) => subT(a, multT(m, quotT(a,m)))
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ export * from './Types/generic.mjs'
|
|||
export const multiply = {
|
||||
'undefined': () => u => u,
|
||||
'undefined,...any': () => (u, rest) => u,
|
||||
any: () => x => x,
|
||||
'any,undefined': () => (x, u) => u,
|
||||
'any,any,...any': ({self}) => (a,b,rest) => {
|
||||
const later = [b, ...rest]
|
||||
|
|
12
src/generic/reducingOperation.mjs
Normal file
12
src/generic/reducingOperation.mjs
Normal file
|
@ -0,0 +1,12 @@
|
|||
export * from './Types/generic.mjs'
|
||||
|
||||
export const reducingOperation = {
|
||||
'undefined': () => u => u,
|
||||
'undefined,...any': () => (u, rest) => u,
|
||||
'any,undefined': () => (x, u) => u,
|
||||
any: () => x => x,
|
||||
'any,any,...any': ({
|
||||
self
|
||||
}) => (a,b,rest) => [b, ...rest].reduce((x,y) => self(x,y), a)
|
||||
}
|
||||
|
54
src/generic/relational.mjs
Normal file
54
src/generic/relational.mjs
Normal file
|
@ -0,0 +1,54 @@
|
|||
export const compare = {
|
||||
'undefined,undefined': () => () => 0
|
||||
}
|
||||
|
||||
export const isZero = {
|
||||
'undefined': () => u => u === 0
|
||||
}
|
||||
|
||||
export const equal = {
|
||||
'!T,T': ({
|
||||
'compare(T,T)': cmp,
|
||||
'isZero(T)': isZ
|
||||
}) => (x,y) => isZ(cmp(x,y))
|
||||
}
|
||||
|
||||
export const unequal = {
|
||||
'T,T': ({'equal(T.T)': eq}) => (x,y) => !(eq(x,y))
|
||||
}
|
||||
|
||||
export const larger = {
|
||||
'T,T': ({
|
||||
'compare(T,T)': cmp,
|
||||
'one(T)' : uno
|
||||
}) => (x,y) => cmp(x,y) === uno(y)
|
||||
}
|
||||
|
||||
export const largerEq = {
|
||||
'T,T': ({
|
||||
'compare(T,T)': cmp,
|
||||
'one(T)' : uno,
|
||||
'isZero(T)' : isZ
|
||||
}) => (x,y) => {
|
||||
const c = cmp(x,y)
|
||||
return isZ(c) || c === uno(y)
|
||||
}
|
||||
}
|
||||
|
||||
export const smaller = {
|
||||
'T,T': ({
|
||||
'compare(T,T)': cmp,
|
||||
'one(T)' : uno,
|
||||
'isZero(T)' : isZ
|
||||
}) => (x,y) => {
|
||||
const c = cmp(x,y)
|
||||
return !isZ(c) && c !== uno(y)
|
||||
}
|
||||
}
|
||||
|
||||
export const smallerEq = {
|
||||
'T,T': ({
|
||||
'compare(T,T)': cmp,
|
||||
'one(T)' : uno
|
||||
}) => (x,y) => cmp(x,y) !== uno(y)
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
export const sign = {
|
||||
any: ({negate, divide, abs}) => x => {
|
||||
if (x === negate(x)) return x // zero
|
||||
return divide(x, abs(x))
|
||||
}
|
||||
T: ({'compare(T,T)': cmp, 'zero(T)': Z}) => x => cmp(x, Z(x))
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const square = {
|
||||
any: ({multiply}) => x => multiply(x,x)
|
||||
T: ({'multiply(T,T)': multT}) => x => multT(x,x)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const subtract = {
|
||||
'any,any': ({add, negate}) => (x,y) => add(x, negate(y))
|
||||
'T,T': ({'add(T,T)': addT, 'negate(T)': negT}) => (x,y) => addT(x, negT(y))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue