From 5805bfeee4c9c2f713042b34e41821be153cac7c Mon Sep 17 00:00:00 2001 From: Xie Yuheng Date: Mon, 24 Jun 2024 20:53:29 +0800 Subject: [PATCH] `utils/coercing` -- improve generic functions --- TODO.md | 31 +++++++++++++++---------------- src/generics/arithmetic.ts | 10 ++++------ src/interval/Interval.ts | 5 +++++ src/utils/coercing.ts | 6 ++++++ 4 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 src/utils/coercing.ts diff --git a/TODO.md b/TODO.md index 9b0aded..c7faed1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,33 +1,32 @@ -improve interface for `put` -- second argument should be list of optional promises - -`applyAfter` (`coercing`) +# propagator 支持 dependencies for provenance -> propagator 支持 dependencies for provenance -> > - https://github.com/cicada-lang/propagator/issues/2 - -测试反向运算的 provenance - -test about "a justified-intervals anomaly" +> `coercing(toInterval, f)` +> `coercing(toSupported, f)` +> 测试反向运算的 provenance +> test about "a justified-intervals anomaly" - 即 supports 的集合可能与 supported value put 进来的顺序有关 +# later + +improve interface for `put` -- second argument should be list of optional promises `utils/Set` -- `setIntersection` & `setDifference` -- 为了完备 -> propagator 支持 dependencies for alternate worldviews -> +# propagator 支持 dependencies for alternate worldviews + > - https://github.com/cicada-lang/propagator/issues/3 -> propagator 支持 dependencies for implicit search -> +# propagator 支持 dependencies for implicit search + > - https://github.com/cicada-lang/propagator/issues/4 -> 完成 "The Art" 中的 Heron 例子 -> +# 完成 "The Art" 中的 Heron 例子 + > - 需要设计 lattice 来逼近结果 > - 一个叫 近似值 的数据类型,并且为 generic 函数实现相关的 handles -> interval 支持完整的 arithmetic,包括正数与负数 +# interval 支持完整的 arithmetic,包括正数与负数 `interval/` -- arithmetic 支持负数 diff --git a/src/generics/arithmetic.ts b/src/generics/arithmetic.ts index d552fc7..ad58e1d 100644 --- a/src/generics/arithmetic.ts +++ b/src/generics/arithmetic.ts @@ -6,18 +6,16 @@ import { intervalMul, intervalSub, isInterval, + toInterval, } from "../interval/index.js" +import { coercing } from "../utils/coercing.js" import { isNumber } from "../utils/isNumber.js" export const add = defineGeneric() defineHandler(add, [isNumber, isNumber], (x, y) => x + y) defineHandler(add, [isInterval, isInterval], intervalAdd) -defineHandler(add, [isInterval, isNumber], (x, y) => - intervalAdd(x, exactInterval(y)), -) -defineHandler(add, [isNumber, isInterval], (x, y) => - intervalAdd(exactInterval(x), y), -) +defineHandler(add, [isInterval, isNumber], coercing(toInterval, intervalAdd)) +defineHandler(add, [isNumber, isInterval], coercing(toInterval, intervalAdd)) export const sub = defineGeneric() defineHandler(sub, [isNumber, isNumber], (x, y) => x - y) diff --git a/src/interval/Interval.ts b/src/interval/Interval.ts index 11dc65a..73fe143 100644 --- a/src/interval/Interval.ts +++ b/src/interval/Interval.ts @@ -21,3 +21,8 @@ export function exactInterval(x: number): Interval { export function isInterval(x: any): x is Interval { return isNonNullObject(x) && x["@type"] === "Interval" } + +export function toInterval(x: number | Interval): Interval { + if (isInterval(x)) return x + return exactInterval(x) +} diff --git a/src/utils/coercing.ts b/src/utils/coercing.ts new file mode 100644 index 0000000..bbc454a --- /dev/null +++ b/src/utils/coercing.ts @@ -0,0 +1,6 @@ +export function coercing( + to: (x: A) => B, + fn: (...args: Array) => C, +): (...args: Array) => C { + return (...args) => fn(...args.map(to)) +}