Skip to content

Repository files navigation

optics-java

optics-java 是一个独立的 Java 光学、HKT、类型代数和优化器实验库。当前重点是把 DataFixerUpper(以下简称 DFU)里和类型重写、无点式优化、递归类型处理等相关的理论部分,用更适合 OELib 的方式重新实现。

DFU 理论重写

本项目基于 DataFixerUpper 的 HKT、光学、无点式重写、类型重写和递归类型重写相关部分做了本地重写。这里并没有完全复刻 DFU,而是抽取其中的理论内核,用作配置库底层。

本项目已经解决了若干 DFU 已知问题:

  • 积类型、和类型、标签选择分支排序后的类型修复 DFU / Issue#108
  • 递归重写中的分支/索引裁剪。
  • 递归 cata/fold 融合的显式依赖证据。
  • ReflexCata 的相等性判断问题,改为显式恒等代数证据。
  • 字段/类型查找统一路径。
  • 递归点的模板贯穿和 μ 边界修复。

新增理论实现

在 DFU 已有思想之外,本项目主要补上了这些理论实现:

  • Java 侧结构化类型代数,把记录、标签选择、密封子类型、递归族槽位等项目需要的类型结构纳入优化器可检查的数据。
  • 四参数带类型光学脊柱:S -> TA -> B 分离,优化器可以在重写后修复光学元数据。
  • fold/query IR,用于 fold-map 融合、积式 fold 融合、preview、first、any、all、count 等查询优化。
  • 通用递归特化,把结构化通用递归函数降到 CataPlan
  • 证据驱动的 ReflexCata,只有显式自反恒等证据和依赖证据足够时才消成恒等函数。

优化器

优化器是一个分层构造的等式重写系统,只在结构信息和类型证据足够时改写表达式,本质是 IR + 一个小型优化编译器。

底层是带类型的无点式 IR,将光学操作拆解为组合子树(组合、应用、恒等、bang、Fn、opticApp、cataPlan 等),使表达式可代数操作。中层是策略式重写引擎,用 topDown、bottomUp、once、many、all、one 等组合子将遍历策略与变换规则解耦。上层是四参数类型化光学脊柱,将光学表示为可检查、可比较、可前缀提取/后缀切分的带类型元素序列——每条光学是一条 profunctor 变换 P A B → P S T。

另外,为了给不同写法也应用这一套优化逻辑,本项目实现了一套小型编译器前端。 它读取可序列化 lambda 的 class-file 字节码并构建 LambdaExpr AST,在结构可证明时提升为专用 optic 节点,无法证明时则保留 opaque 语义。此篇讲了什么写法会被优化,什么不会 optics-usage-contract

应用一次性提供自身的 MethodHandles.Lookup:可在 JPMS 的 module-info.java 中注册 OpticsLookupProvider,可在 classpath 下使用 META-INF/services,框架也可在收到业务 lookup 后调用 OpticsLookups.register(lookup);之后仍直接使用 Lens.ofTraversal.ofPrism.subtypeOptics.*,无需在每次调用时传 lookup。配置方式见 optics-usage-contract

性能结论

在真实应用型迁移基准中,本项目与 DFU 基本持平。把优化器场景单独拆出来看,两边仍会出现差异,整体属于平分秋色:有 DFU 更高的地方,也有本项目更高的地方。

本项目在优化器里保留了更严格的理论检查,因此部分单独拆出的优化器场景可能因为这些检查而不如 DFU,但真实开发中这类差异影响微乎其微。

主要模块

HKT 与类型类

基础 HKT 编码使用 K1K2AppApp2Kind1Kind2 表示一元和二元类型构造子应用。当前包含的类型类和能力接口主要有:

  • Functor
  • Applicative
  • Selective
  • Monad
  • Contravariant
  • Bifunctor
  • Natural
  • Semigroup
  • Monoid
  • Foldable
  • Traversable
  • Profunctor
  • Cartesian
  • Strong
  • Cocartesian
  • Choice
  • Closed
  • Traversing
  • Mapping
  • AffineP
  • Monoidal
  • MonoidProfunctor
  • FunctorProfunctor
  • ReCartesian
  • ReCocartesian

核心 profunctor carrier 和辅助结构包括:

  • FunctionArrow
  • Forget
  • ForgetE
  • ForgetOpt
  • ReForget
  • ReForgetC
  • ReForgetE
  • ReForgetP
  • ReForgetEP
  • Procompose
  • Const
  • Grate
  • Wander

核心数据类型包括:

  • Maybe<A>
  • Either<L, R>
  • Try<A>
  • Validated<E, A>
  • CheckedFunction<A, B, X> 等 checked-function 接口
  • Tuple2<A, B>
  • Tuple3<A, B, C>
  • Tuple4<...>Tuple16<...>
  • IdF<A>
  • Unit

Math

时尚小垃圾。

com.flechazo.math 是一组用于验证和复用 HKT 表达能力的后端无关抽象。它允许你把态射、函子、坐标无关线性映射、张量形状、标量扩张和算子签名编码进 Java 类型, 并把表达式重化为可由 Natural transformation 解释的数学 IR。

对于 99.99% 的情况,这个包完全没有用。它不是数学计算库,不提供向量、矩阵、四元数或张量的具体值实现,也不提供数值算法、存储结构、SIMD、求解器或任何第三方数值后端适配。

本项目不选择、不包装也不发布数值后端;IR 只保存类型、变量、字面量和算子应用,不负责计算、优化或求值。

业务 API

业务能力接口包括:

  • Composable<A>
  • Combinable<A>
  • Chainable<A>
  • Effectful<A>
  • Recoverable<E, A>
  • Accumulating<E, A>

业务组合入口和路径类型包括:

  • Pathway
  • MaybePath<A>
  • EitherPath<E, A>
  • TryPath<A>
  • ValidationPath<E, A>
  • ListPath<A>
  • ReaderPath<R, A>
  • WriterPath<W, A>
  • WithStatePath<S, A>
  • LazyPath<A>
  • VTaskPath<A>
  • IOPath<A>
  • ResourcePath<A>
  • IOResourcePath<A>
  • CompletableFuturePath<A>
  • StreamPath<A>
  • VStreamPath<A>

业务上下文、控制和 effect 数据类型包括:

  • Reader<R, A>
  • Writer<W, A>
  • State<S, A>
  • StateResult<S, A>
  • ListK<A>
  • ValidatedNel
  • NonEmptyList<A>
  • Lazy<A>
  • VTask<A>
  • IO<A>
  • Resource<A>
  • IOResource<A>
  • ExitCase
  • Finalizers

业务 resilience API 包括:

  • Resilience
  • ResilienceBuilder<A>
  • Retry
  • RetryPolicy
  • RetryEvent
  • CircuitBreaker
  • CircuitBreakerConfig
  • CircuitBreakerMetrics
  • Bulkhead
  • BulkheadConfig
  • Saga<A>
  • SagaBuilder<A>
  • SagaStep<A>
  • SagaError

业务 stream API 包括:

  • StreamK<A>
  • FStream<F, A>
  • VStream<A>
  • VStreamPar
  • VStreamReactive
  • VStreamThrottle
  • VStreamInstance

业务辅助 API 包括:

  • Attempts
  • Monoids
  • Semigroups
  • Traverses
  • OptionalOps

函数式异常与资源处理

会声明 checked exception 的 Java API 可以直接进入显式失败通道,不需要在 lambda 中手写 try/catch

Try<String> content = Try.success(path)
        .mapChecked(Files::readString)
        .recover(NoSuchFileException.class, ignored -> "");

IO<String> deferred = IO.pure(path)
        .mapChecked(Files::readString);

Attempts.liftTry 用于 JDK Stream 等只接受普通 Function 的 API; Attempts.uncheckedFunction 只用于明确要求 unchecked 传播的边界,并要求调用方 显式提供异常映射。批量转换使用 Attempts.traverse 进行 fail-fast 处理,或使用 Attempts.validateAll 累计错误。

资源获取和释放使用 Resource / IOResourcemakeCase 的 finalizer 会收到 ExitCase.SucceededExitCase.FailedExitCase.Canceled;多个 finalizer 通过 Finalizers.vtaskMonoid()Finalizers.ioMonoid() 组合,全部执行并按顺序保留 suppressed failure。普通 optic getter、rebuilder 和 modifier 仍必须保持纯函数; 需要失败或 I/O 时使用 modifyF,具体契约见 docs/optics-usage-contract.md

光学

核心光学 API 包括:

  • Iso<S, A>
  • Lens<S, A>
  • Prism<S, A>
  • Affine<S, A>
  • Traversal<S, A>
  • Fold<S, A>
  • Getter<S, A>
  • Setter<S, A>
  • Optic<S, T, A, B>

多态光学 API 包括:

  • PIso<S, T, A, B>
  • PLens<S, T, A, B>
  • PPrism<S, T, A, B>
  • PAffine<S, T, A, B>
  • PTraversal<S, T, A, B>
  • PSetter<S, T, A, B>

带索引光学包括:

  • IndexedOptic<I, S, A>
  • IndexedLens<I, S, A>
  • IndexedTraversal<I, S, A>
  • IndexedGetter<I, S, A>
  • IndexedFold<I, S, A>

光学语义函数接口包括:

  • LensGetter<S, A>
  • LensRebuilder<S, A, T>
  • IsoGetter<S, A>
  • IsoRebuilder<A, S>
  • PrismMatcher<S, T, A>
  • PrismBuilder<A, S>
  • AffinePreview<S, T, A>
  • AffineRebuilder<S, A, T>
  • GetterReader<S, A>
  • FoldGetter<S, A>
  • WanderGetter<S, A>
  • WanderRebuilder<S, A>
  • SetterModifier<S, T, A, B>

常用实例和工具包括:

  • Optics
  • Each
  • Ixed
  • At
  • Traversals
  • Prisms
  • Affines
  • ListPrisms
  • ListTraversals
  • StringTraversals
  • EitherTraversals
  • TryTraversals
  • ValidatedTraversals
  • TupleTraversals

Focus DSL

com.flechazo.optics.focus 提供轻量焦点 DSL,用于把生成出的焦点路径继续组合到 lens、traversal、affine 等光学结构。

参考:

Optimizing functions:

How to handle recursive types:

Optics:

Tying it together:

class-file 字节码后端

本项目使用 Class File API 生成隐藏类执行器。字节码后端会先运行标准优化器,再为支持的无点式计划生成专用执行器/函数类;不支持的节点保留解释执行兜底路径。

构建要求

本项目基于 Java 21 构建。

主要依赖:

  • io.smallrye.classfile:jdk-classfile-backport

About

A simplified Java optics library

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages