Focus | project | refract. A typed transformation pipeline in Rust.
Result extended with partial success. Three states: Success, Partial (value + measured loss), Failure. The Loss trait measures what didn't survive a transformation. Standalone crate, no dependencies on prism.
Beam (semifunctor) + Prism (monoid). A Beam carries a value, the input that produced it, and accumulated loss through a pipeline. A Prism defines three operations over beams: focus (select), project (transform), refract (produce output). The three operations compose into type-safe pipelines enforced at compile time.
imperfect (standalone, zero dependencies)
^
|
prism-core (depends on imperfect, zero external dependencies)
use prism_core::{Beam, Prism, Optic, Focus, Project, Refract};
use terni::Imperfect;
// Seed a beam and run it through a prism
let result = Optic::ok((), "hello".to_string())
.apply(Focus(&my_prism))
.apply(Project(&my_prism))
.apply(Refract(&my_prism));
assert!(result.is_ok());Each apply step is type-checked: the output type of one stage must match the input type of the next. Mismatches are compile errors, not runtime panics.
435 tests across the workspace:
nix develop -c cargo test --workspace --features optics,bundle
TBD