Focus | project | settle. 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. Source: imperfect/.
Beam (semifunctor) + Prism (monoid). A Beam carries a value, the input that produced it, and accumulated loss through a pipeline. A Prism defines five operations over beams: focus, project, split, shift, settle. They compose into type-safe pipelines enforced at compile time. Source: prismqueer/.
Proc-macros for prismqueer: #[derive(Prism)], #[oid], declaration!. Source: projections/.
terni (standalone, zero deps)
^
|
prismqueer-projections (proc-macros, depend on prismqueer types at expansion)
^
|
prismqueer (depends on terni, zero external deps)
use prismqueer::{Beam, Prism, Optic, Focus, Project, Settle};
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(Settle(&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