架构
本指南介绍仓库的组织方式以及各部分如何协同工作。各项决策背后的理由见 core 设计页。
源码布局
模块 Luna-Flow/arithmetic 只有一个包,位于 src/。
| 文件 | 内容 |
|---|---|
elementary.mbt | 非检查 trait:Sqrt、Cbrt、Radical、Exponential、Logarithmic、Power、Trigonometric、InverseTrigonometric、Hyperbolic、InverseHyperbolic、Constants |
checked.mbt | FpClass、RoundingMode、ArithmeticContext、错误与认证相关类型、检查 trait 以及包络关系 trait |
contextual.mbt | ArithmeticDiagnostics、ArithmeticOutcome 以及上下文 trait |
impl_double.mbt, impl_float.mbt | Double 和 Float 的非检查实例与检查实例 |
impl_contextual.mbt | Double 和 Float 的上下文实例 |
impl_signed_ints.mbt, impl_unsigned_ints.mbt, impl_bigint.mbt | 整数类型的 Power |
extends.mbt | 显式方法提升(pub extend ... with Eq::{equal})以及已弃用的隐式形式 |
pkg.generated.mbti | 生成的公开接口,是判断哪些内容公开的权威依据 |
测试与源码放在一起:trait_test.mbt 和 contextual_test.mbt 是以 @arithmetic 调用本包的黑盒测试,certification_error_wbtest.mbt 是白盒测试。
依赖
| 依赖项 | 用途 |
|---|---|
Kaida-Amethyst/math (@km) | Float 和 Double 的初等函数 |
moonbitlang/core/math | @math.PI |
moonbitlang/core/debug | 已弃用的 Debug::to_repr 提升 |
Luna-Flow/luna-generic(@lf_alg,仅用于测试) | 检查各实例能否与代数 trait 配合使用 |
公开 API 不涉及 luna-generic:两个包可以在约束中组合使用,但运行时互不依赖。
边界模型
| 边界 | 返回值 | 含义 |
|---|---|---|
| 非检查 trait | Self | 后端自身的行为,包括 NaN、回绕或中止 |
| 检查 trait | Result[T, ArithmeticError] | 被拒绝的运算是一个错误值 |
| 上下文 trait | Result[ArithmeticOutcome[T], ArithmeticError] | 显式上下文;成功时附带诊断 |
| 包络关系 | Bool | 包含关系,或确定 / 可能成立的关系 |
各层级是相互独立的 trait,彼此没有 supertrait 关系,因此一个类型可以实现其中任意子集。
错误、诊断与认证
错误表示运算没有产生可接受的结果。诊断描述带有值得注意的条件(舍入、上溢、下溢、钳制)的成功结果,并以逻辑或组合。认证失败是一种错误,其详细信息记录了基于证明的求值所处的阶段、原因、目标精度与工作精度以及细化次数;本包不规定任何重试策略。
上下文与状态
ArithmeticContext、ArithmeticDiagnostics、ArithmeticOutcome 和 CertificationFailureDetail 都是字段只读的不可变值。上下文是参数,诊断是返回值的一部分,认证证据随错误一起传递。不存在全局舍入模式、状态寄存器或可变的证明状态,因此同一调用在每个目标平台上都给出相同的结果。
内置实例
Float 和 Double 实现了所有非检查 trait,检查形式的平方根、除法、比较和整数次幂,以及上下文形式的算术运算、绝对值、平方根、指数函数、整数嵌入、相邻值和格式查询。它们的上下文实例会忽略上下文;只有 Float 的整数嵌入会报告舍入。它们不实现 ConstantsContextual、HyperbolicContextual、ParseChecked 以及包络关系。整数类型和 BigInt 只实现 Power。完整表格见 API 页。
公开接口与方法提升
自 MoonBit 0.10 起,trait 实现不再自动把 trait 的方法变成该类型的方法。extends.mbt 声明了哪些方法被提升:每个公开类型都提升 equal,因此 x.equal(y) 和 T::equal 仍然可用。原先隐式存在的 not_equal 和 to_repr 方法作为已弃用的隐藏提升保留,以保持兼容。moon info 会重新生成 pkg.generated.mbti;每次改动公开接口时都应审查其差异。