fp-ts Bounded 类型类完全指南:为全序类型定义上下界与边界钳制
fp-ts Bounded 类型类完全指南为全序类型定义上下界与边界钳制【免费下载链接】fp-tsFunctional programming in TypeScript项目地址: https://gitcode.com/gh_mirrors/fp/fp-tsBounded是 fp-ts 中在Ord全序基础上进一步收窄的一类抽象它不仅定义了类型元素之间的比较关系还规定了该类型在序意义下的最大元素top与最小元素bottom。本文以 docs/modules/Bounded.ts.md 为骨架结合 src/Bounded.ts 的源码实现与 test/Bounded.ts 的测试用例系统讲解Bounded接口、clamp/reverse两个实用工具函数以及它如何支撑Monoid、Semigroup等模块构造出取最小值、最大值的代数结构。读完本文你将掌握如何为自定义类型声明有界序、如何将任意值钳制到合法区间、如何反转一个边界并理解 fp-ts 中Bounded与Ord、number实例之间的真实调用关系。Bounded 是什么在全序之上追加边界Bounded是一个类型类type class它表示具有上界和下界的全序类型。用 src/Bounded.ts 顶部注释中的话说TheBoundedtype class represents totally ordered types that have an upper and lower boundary.也就是说一个类型要成为Bounded首先必须是一个Ord全序任意两个元素都可比较其次必须在序关系中存在唯一的最大元素top和最小元素bottom。典型例子是number任意两个数字可比较大小且Infinity是上界、-Infinity是下界。该类型类自v2.0.0起引入见 src/Bounded.ts 的since 2.0.0标注在 src/index.ts 中作为bounded命名空间整体导出import * as bounded from ./Bounded因此既可以从fp-ts/Bounded按模块引入也可以从fp-ts入口统一使用。Bounded 定律在 Ord 定律之外的追加约束Bounded的实例除了必须满足Ord的全部定律外还必须满足一条额外定律Bounded: bottom a top即对类型A的任意元素a按该实例的比较关系bottom不大于aa不大于top。这条定律保证了bottom与top确实是序意义上的边界而不是任意挑选的两个值。Ord本身的定律包括自反性S.compare(a, a) 0、反对称性与传递性可参见 src/Ord.ts 顶部注释Bounded在其上叠加了边界约束。Bounded 接口Ord 的边界扩展BoundedA接口定义在 src/Bounded.ts 的 model 区域export interface BoundedA extends OrdA { readonly top: A readonly bottom: A }它通过接口继承扩展了 src/Ord.ts 中的OrdAOrd本身又继承EqA包含equals与compare两个字段并额外声明两个只读字段top: A—— 序意义下的最大元素bottom: A—— 序意义下的最小元素。由于Ord已经包含compare: (first, second) Ordering与equals因此构造一个BoundedA实例时你需要同时提供比较逻辑和两个边界值。测试 test/Bounded.ts 展示了最典型的构造方式——基于number的Ord展开并补充边界const B: _.Boundednumber { ...N.Ord, top: 10, bottom: 0 }这里的N.Ord来自 src/number.ts 的Ord实例compare按/返回-1/1/0展开后得到一个0到10之间的有界数字序。现成的 number 实例Bounded仓库为最常用的number类型提供了开箱即用的Bounded实例定义在 src/number.tsexport const Bounded: B.Boundednumber { equals: Eq.equals, compare: Ord.compare, top: Infinity, bottom: -Infinity }该实例以Infinity为上界、-Infinity为下界对应number在全序意义下没有真边界的数学事实——任何有限数字都落在两者之间因此严格满足bottom a top定律。日常开发中建议直接使用import * as N from fp-ts/number后引用N.Bounded。clamp将任意值钳制到 [bottom, top] 区间clamp是Bounded模块中最常用的实用函数自v2.12.0加入export declare const clamp: A(B: BoundedA) (a: A) A签名采用柯里化先传入一个BoundedA实例再传入待处理的元素a返回钳制后的元素。若a小于bottom则返回bottom若a大于top则返回top否则原样返回a。底层实现原理其实现只有一行位于 src/Bounded.tsexport const clamp A(B: BoundedA): ((a: A) A) O.clamp(B)(B.bottom, B.top)它复用了Ord模块的clamp见 src/Ord.tsexport const clamp A(O: OrdA): ((low: A, hi: A) (a: A) A) { const minO min(O) const maxO max(O) return (low, hi) (a) maxO(minO(a, hi), low) }Ord.clamp的实现逻辑是先用min(O)求出a与hi的较小者保证不超上界再用max(O)与low取较大者保证不低于下界即max(min(a, hi), low)。Bounded.clamp的关键在于自动把B.bottom与B.top填入low/hi参数调用者无需再手动传边界。注意这里的min/max分别对应 src/Ord.ts 中的min相等时选第一个参数与max相等时选第一个参数。实测验证test/Bounded.ts 对clamp给出了三组断言const B: _.Boundednumber { ...N.Ord, top: 10, bottom: 0 } const clamp _.clamp(B) clamp(5) // 5落在区间内原样返回 clamp(-1) // 0低于 bottom钳制为 bottom clamp(11) // 10高于 top钳制为 top实战示例分数百分制归一化一个典型的应用场景是数据校验后的区间归一化例如把任意打分钳制到 0100import * as B from fp-ts/Bounded import * as N from fp-ts/number // 自定义一个 0~100 的有界数字序 const scoreBound: B.Boundednumber { ...N.Ord, top: 100, bottom: 0 } const clampScore B.clamp(scoreBound) clampScore(95) // 95 clampScore(-30) // 0 clampScore(150) // 100reverse反转序并交换边界reverse同样自v2.12.0加入作用是反转Bounded实例的比较方向同时交换top与bottomexport declare const reverse: A(B: BoundedA) BoundedA语义上反转一个有界序包含两个动作一是比较关系反转原先是升序反转后为降序二是原本的top在新的序中变成最小元素、原本的bottom变成最大元素因此两者必须互换才能保证反转后依然满足bottom a top定律。底层实现原理源码位于 src/Bounded.tsexport const reverse A(B: BoundedA): BoundedA { const R O.reverse(B) return { equals: R.equals, compare: R.compare, top: B.bottom, bottom: B.top } }实现分两步调用O.reverse(B)得到反转后的Ord。Ord.reverse定义在 src/Ord.ts实现为fromCompare((first, second) O.compare(second, first))即交换两个比较参数等价于compare(a, b)变为compare(b, a)将equals与compare取自反转后的R同时把top赋值为原B.bottom、bottom赋值为原B.top。实测验证test/Bounded.ts 验证了边界交换行为const B: _.Boundednumber _.reverse({ ...N.Ord, top: 10, bottom: 0 }) B.top // 0原 bottom B.bottom // 10原 top实战示例排行榜降序有界区间例如要处理最高分优先级最高的降序场景同时仍希望保留边界语义分数不超出 0100import * as B from fp-ts/Bounded const asc: B.Boundednumber { ...N.Ord, top: 100, bottom: 0 } const desc B.reverse(asc) desc.compare(90, 10) // -190 在降序中更小更靠前 desc.top // 0 desc.bottom // 100从源码看 Bounded 的生态位置Bounded在 fp-ts 中并不是孤立模块它向下依赖Ord向上支撑多个代数结构的构造器支撑 Monoid 的 min / max 构造器src/Monoid.ts 使用Bounded构造取最小值和最大值的Monoidexport const min A(B: BoundedA): MonoidA ({ concat: Se.min(B).concat, empty: B.top }) export const max A(B: BoundedA): MonoidA ({ concat: Se.max(B).concat, empty: B.bottom })逻辑非常直观取最小值的幺半群其恒等元必须是不影响取最小值结果的值即序的最大元素top反之取最大值的幺半群恒等元为bottom。而concat复用 src/Semigroup.ts 中基于Ord的min/max内部调用Or.min(O)/Or.max(O)即 src/Ord.ts 的min/max。这形成一个清晰的依赖链Bounded→Ord→ 比较原语。典型用法import * as N from fp-ts/number import * as M from fp-ts/Monoid const minMonoid M.min(N.Bounded) minMonoid.concat(1, 2) // 1 minMonoid.empty // Infinity const maxMonoid M.max(N.Bounded) maxMonoid.concat(1, 2) // 2 maxMonoid.empty // -Infinity为 Const 提供有界实例src/Const.ts 通过getBounded将任意BoundedE提升为BoundedConstE, Aexport const getBounded: E, A(B: BoundedE) BoundedConstE, A identity as any它利用Const类型擦除的特性直接复用底层BoundedE说明Bounded作为携带序信息的实例可以借助类型构造器在更复杂的结构中传播。依赖关系小结BoundedA继承OrdAsrc/Bounded.tsOrdA继承EqAsrc/Ord.tsnumber模块提供现成的Boundednumber实例src/number.tsMonoid.min/Monoid.max消费Bounded实例src/Monoid.tsConst.getBounded复用Bounded实例src/Const.ts。迁移说明boundedNumber 已废弃原Bounded模块在 v2.0.0 曾导出一个名为boundedNumber的Boundednumber常量现已被标记为deprecatedzone of death不再建议直接使用export declare const boundedNumber: Boundednumber其历史实现见 src/Bounded.ts 的 deprecated 区域为export const boundedNumber: Boundednumber { equals: O.ordNumber.equals, compare: O.ordNumber.compare, top: Infinity, bottom: -Infinity }它的功能与现在的N.Bounded完全等价。官方迁移指引是改用number模块中的Bounded实例即import * as N from fp-ts/number后使用N.Bounded。这一迁移也符合 fp-ts v2.10 将各基础类型的实例收敛到对应模块number、string、boolean等的整体设计趋势。如果你的代码中仍在使用boundedNumber编译时会出现废弃警告建议按此路径平滑升级。小结Bounded在 fp-ts 的类型类体系中扮演有边界的全序这一角色BoundedA extends OrdA并追加top/bottom两个边界字段实例必须满足bottom a top定律。围绕它clamp把任意值钳制到边界区间复用Ord.clamp并以B.bottom/B.top自动填充reverse在反转比较方向的同时交换上下界复用Ord.reverse。在生态上它是Monoid.min/Monoid.max构造器的输入来源也被Const.getBounded复用。对于数字等常见类型直接使用N.Boundedtop: Infinity、bottom: -Infinity即可不必再碰已废弃的boundedNumber。相关实现与验证可进一步阅读 src/Bounded.ts、src/Ord.ts、src/number.ts、src/Monoid.ts 与 test/Bounded.ts。【免费下载链接】fp-tsFunctional programming in TypeScript项目地址: https://gitcode.com/gh_mirrors/fp/fp-ts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

FURUNO FAR-28x7 雷达操作与维护全指南:从按键到避碰

FURUNO FAR-28x7 雷达操作与维护全指南:从按键到避碰

简介:这份FURUNO雷达使用说明书PDF面向船舶驾驶人员、航海电子设备维护者及航运院校师生,针对FAR-2817/2827/2837S系列雷达的日常操作与功能理解需求,帮助读者掌握ARPA与AIS一体化航海雷达的使用方法。资源包共1个文件,为PDF格式&…

2026/9/23 14:05:02 阅读更多 →
SciPy `kstwo` 分布详解:双样本 Kolmogorov-Smirnov 统计量的精确概率分布

SciPy `kstwo` 分布详解:双样本 Kolmogorov-Smirnov 统计量的精确概率分布

SciPy kstwo 分布详解:双样本 Kolmogorov-Smirnov 统计量的精确概率分布 【免费下载链接】scipy SciPy library main repository 项目地址: https://gitcode.com/gh_mirrors/sc/scipy 导读 本文围绕 SciPy 官方教程文档 continuous_kstwo.rst 展开&#xff…

2026/9/23 14:05:02 阅读更多 →
Python实现商店阶梯折扣计算:从基础到优化

Python实现商店阶梯折扣计算:从基础到优化

1. 项目背景与需求解析商店折扣计算是商业活动中最基础的财务场景之一,也是编程初学者练习条件判断的经典案例。这个题目模拟了真实购物场景中常见的阶梯式折扣策略,要求根据消费金额自动计算最终应付金额。在实际商业环境中,这种定价策略被称…

2026/9/23 14:05:02 阅读更多 →

最新新闻

3个致命Bug让你白干:一文搞懂词库网API接入避坑指南

3个致命Bug让你白干:一文搞懂词库网API接入避坑指南

3个致命Bug让你白干:一文搞懂词库网API接入避坑指南 刚把同事甩过来的代码扔进本地环境,点下运行,报错 IndexError: list index out of range…

2026/9/23 14:44:03 阅读更多 →
LSMW录屏批量上载全解析:从SHDB录屏到字段映射与排错

LSMW录屏批量上载全解析:从SHDB录屏到字段映射与排错

简介:这是一份讲解SAP LSMW录屏批量上载操作的手册,面向需要完成数据迁移的SAP实施顾问、内部顾问与运维人员。资源采用Batch Input Recording这一常用录屏方式,围绕LSMW工具的操作主线展开,覆盖Project/Subproject创建、批输入录…

2026/9/23 14:44:03 阅读更多 →
Relay 类型安全更新器(Typesafe Updaters)FAQ 深度指南:readUpdatableQuery 与 readUpdatableFragment 实战解析

Relay 类型安全更新器(Typesafe Updaters)FAQ 深度指南:readUpdatableQuery 与 readUpdatableFragment 实战解析

Relay 类型安全更新器(Typesafe Updaters)FAQ 深度指南:readUpdatableQuery 与 readUpdatableFragment 实战解析 【免费下载链接】relay Relay is a JavaScript framework for building data-driven React applications. 项目地址: https:/…

2026/9/23 14:44:03 阅读更多 →
AI科研编程核心应用场景与落地实践指南

AI科研编程核心应用场景与落地实践指南

刚接触科研时,光是各种免费文献网站的推荐就让我眼花缭乱,每个都试一下,结果哪个都没用透,效率极低。直到我静下心来深度测试,才发现真正能称为“天花板”的网站,只需要四个。尤其是第一个,它能…

2026/9/23 14:44:03 阅读更多 →
Apache TVM 贡献者指南:从提交 PR、代码评审到版本发布的完整协作流程

Apache TVM 贡献者指南:从提交 PR、代码评审到版本发布的完整协作流程

编译器深度学习模型优化 【免费下载链接】tvm Open deep learning compiler stack for cpu, gpu and specialized accelerators 项目地址: https://gitcode.com/gh_mirrors/tvm7/tvm 点击查看 免费下载 本篇指南以 Apache TVM(面向 CPU、GPU 与专用加速…

2026/9/23 14:44:03 阅读更多 →
357张小样本室内积水检测:VOC转YOLO与迁移学习实战

357张小样本室内积水检测:VOC转YOLO与迁移学习实战

简介:这是一份面向目标检测学习与室内积水场景识别任务的数据集,包含357张已标注jpg图片,配套Pascal VOC与YOLO两种格式标注文件,类别为“jishui”共378个矩形框,适合用于训练积水检测模型或作为YOLO、Faster R-CNN等算…

2026/9/23 14:43:02 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →