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), } }