Skip to main content

Crate terni

Crate terni 

Source
Expand description

I wanna thank Brené Brown for her work.

Result extended with partial success. Three states:

  • Success(T) — the transformation preserved everything. Zero loss.
  • Partial(T, L) — a value came through, but something was lost getting here. The loss is measured and carried forward.
  • Failure(E, L) — no value survived, but the cost of getting here is measured. The accumulated loss tells you what it cost to arrive at this failure.

The middle state is the point. Most real transformations are not perfect and not failed. They are partial: a value exists, and it cost something. Collapsing that into Ok or Err destroys the information about what was lost.

Loss is the trait that measures what didn’t survive. Each domain carries its own loss type: ConvergenceLoss for iterative refinement, ApertureLoss for partial observation, RoutingLoss for decision uncertainty.

§Constructors

use terni::{Imperfect, ConvergenceLoss};

// The four ways to construct an Imperfect:
let perfect: Imperfect<i32, String, ConvergenceLoss> = Imperfect::Success(42);
let lossy: Imperfect<i32, String, ConvergenceLoss> = Imperfect::Partial(42, ConvergenceLoss::new(3));
let failed: Imperfect<i32, String, ConvergenceLoss> = Imperfect::Failure("gone".into(), ConvergenceLoss::new(0));
let failed_with_cost: Imperfect<i32, String, ConvergenceLoss> = Imperfect::Failure("gone".into(), ConvergenceLoss::new(5));

assert!(perfect.is_ok());
assert!(lossy.is_partial());
assert!(failed.is_err());
// Failure carries accumulated loss — the cost of getting here:
assert_eq!(failed_with_cost.loss().steps(), 5);

§The Terni-Functor

Imperfect is a terni-functor — a three-state composition that accumulates loss through the middle state. The bind operator comes in three flavors:

  • .eh() — the shrug. For engineers who get it.
  • .imp() — the name. For the mischievous ones.
  • .tri() — the math. For engineers who know what a terni-functor is.

§Pipeline

use terni::{Imperfect, ConvergenceLoss};

let result = Imperfect::<i32, String, ConvergenceLoss>::Success(1)
    .eh(|x| Imperfect::Success(x * 2))
    .eh(|x| Imperfect::Partial(x + 1, ConvergenceLoss::new(3)));

assert!(result.is_partial());
assert_eq!(result.ok(), Some(3));

§Recovery

use terni::{Imperfect, ConvergenceLoss};

// Recovery from failure always produces Partial — the failure happened,
// and that cost is carried forward.
let failed: Imperfect<i32, String, ConvergenceLoss> =
    Imperfect::Failure("gone".into(), ConvergenceLoss::new(3));

let recovered = failed.recover(|_e| Imperfect::Success(0));

assert!(recovered.is_partial());  // never Success — the failure was real
assert_eq!(recovered.loss().steps(), 3);  // cost survives
assert_eq!(recovered.ok(), Some(0));

§Explicit Context

use terni::{Imperfect, Eh, ConvergenceLoss};

let mut eh = Eh::new();
let a = eh.imp(Imperfect::<i32, String, ConvergenceLoss>::Success(1)).unwrap();
let b = eh.imp(Imperfect::<_, String, _>::Partial(a + 1, ConvergenceLoss::new(5))).unwrap();
let result: Imperfect<i32, String, ConvergenceLoss> = eh.finish(b);

assert!(result.is_partial());

Structs§

ApertureLoss
Which dimensions were dark during observation. Zero means all observed. Combine takes the union of dark dims. Total is represented by aperture = 1.0.
ConvergenceLoss
Distance to crystal. Zero means crystallized. Combine takes the max (the furthest from crystal dominates).
Eh
Terni-functor composition context.
RoutingLoss
Decision uncertainty at a routing point. Zero means one model at 100%. Combine takes max entropy (most uncertain dominates).

Enums§

Imperfect
Result extended with partial success.

Traits§

Loss
A measure of what didn’t survive a transformation.