import { and } from './Filter'
import { clamp, clampIn } from './arithmetic/clamp'
import { getDeltas } from './arithmetic/getDeltas'
import { getShare } from './arithmetic/getShare'
import { halve } from './arithmetic/halve'
import { sum, sumAmounts, sumMap } from './arithmetic/sum'
import { getQuotientOf } from './Quotient/getQuotientOf'
export type UnaryOperation = (a: A) => Out
export type BinaryOperationS = (a: A, b: B) => Out
export type BinaryOperationD = (a: A) => (b: B) => Out
export type BinaryOperation = BinaryOperationS & BinaryOperationD
export type TernaryOperationD = (a: A, b: B) => (value: V) => Out
export type AutoUnaryOperation = UnaryOperation
export type AutoBinaryOperation = BinaryOperation
export type BooleanBinaryOperation = BinaryOperation
export type PartialBooleanBinaryOperation = BinaryOperation
export interface BasicType {
zero: N
one: N
}
export interface ConversionsFrom {
fromNumber: (v: number) => N
fromString: (v: string) => N
}
export interface HomoBasicOperations {
add: AutoBinaryOperation
sub: AutoBinaryOperation
mul: AutoBinaryOperation
div: AutoBinaryOperation
mod: AutoBinaryOperation
}
export interface HomoBasicComparators {
eq: BooleanBinaryOperation
lt: BooleanBinaryOperation
gt: BooleanBinaryOperation
lte: BooleanBinaryOperation
gte: BooleanBinaryOperation
}
export interface PartialOrder {
eq: PartialBooleanBinaryOperation
lt: PartialBooleanBinaryOperation
gt: PartialBooleanBinaryOperation
lte: PartialBooleanBinaryOperation
gte: PartialBooleanBinaryOperation
}
export interface HeteroBasicOperations {
add: BinaryOperation
sub: BinaryOperation
mul: BinaryOperation
div: BinaryOperation
mod: BinaryOperation
}
export interface HeteroComparators {
eq: BinaryOperation
lt: BinaryOperation
gt: BinaryOperation
lte: BinaryOperation
gte: BinaryOperation
}
/**
* use purry() to implement functions that support currying
*/
export interface BasicArithmetic extends BasicType, HomoBasicComparators, ConversionsFrom, HomoBasicOperations {
min: AutoBinaryOperation // TODO: define in terms of lt
max: AutoBinaryOperation // TODO: define in terms of gt
abs: AutoUnaryOperation
sqrt: AutoUnaryOperation
}
export interface WithTernaryComparisons {
gtelte: TernaryOperationD
gtlte: TernaryOperationD
gtelt: TernaryOperationD
gtlt: TernaryOperationD
}
export const getTernaryComparisons = (arithmetic: BasicArithmetic) => {
const { eq, lt, gt, lte, gte } = arithmetic
return {
gtelte: (lower: N, upper: N) => and([gte(lower), lte(upper)]),
gtlte: (lower: N, upper: N) => and([gt(lower), lte(upper)]),
gtelt: (lower: N, upper: N) => and([gte(lower), lt(upper)]),
gtlt: (lower: N, upper: N) => and([gt(lower), lt(upper)]),
}
}
export const getAdvancedOperations = (arithmetic: BasicArithmetic) => {
return {
sum: sum(arithmetic),
sumMap: sumMap(arithmetic),
sumAmounts: sumAmounts(arithmetic),
halve: halve(arithmetic),
clamp: clamp(arithmetic),
clampIn: clampIn(arithmetic),
getShare: getShare(arithmetic),
getQuotientOf: getQuotientOf(arithmetic),
getDeltas: getDeltas(arithmetic),
}
}