Alt Family
Fallback and choice combinators: Alt, Plus, Alternative.
Hierarchy
The Alt branch of the functor hierarchy provides combinators for expressing fallback and choice. Alt gives an associative choice operation, Plus adds an identity element (zero/empty), and Alternative combines Plus with Applicative via a blanket impl.
Alt
Alt
Signature
pub trait Alt: Functor {
fn alt<A>(fa1: Self::Of<A>, fa2: Self::Of<A>) -> Self::Of<A>;
}
alt takes two values of the same functor type and returns one, preferring the first when both are "successful." The exact semantics depend on the instance: for OptionF it is .or(), for VecF it is concatenation.
Laws
Instances
| Type constructor | Behaviour of alt |
|---|---|
OptionF | fa1.or(fa2) — returns the first Some, or None if both are None |
ResultF<E> | fa1.or(fa2) — returns the first Ok, or the second value if the first is Err |
VecF | Concatenation — extends fa1 with all elements of fa2 |
NonEmptyVecF | Concatenation — appends the head and tail of fa2 onto fa1 |
VecF and NonEmptyVecF require the alloc or std feature.
Example
use karpal_std::prelude::*;
// Fallback: try the first source, fall back to the second
let primary: Option<i32> = None;
let fallback: Option<i32> = Some(42);
let result = OptionF::alt(primary, fallback);
assert_eq!(result, Some(42));
// When both are present, the first wins
let result = OptionF::alt(Some(1), Some(2));
assert_eq!(result, Some(1));
// Vec: concatenation
let combined = VecF::alt(vec![1, 2], vec![3, 4]);
assert_eq!(combined, vec![1, 2, 3, 4]);
Plus
Plus
Signature
pub trait Plus: Alt {
fn zero<A>() -> Self::Of<A>;
}
zero produces the identity element for alt. Combined with the Alt laws, this gives a monoid structure over the functor type.
Laws
Instances
| Type constructor | zero() returns |
|---|---|
OptionF | None |
VecF | Vec::new() (empty vector) |
ResultF<E> does not implement Plus because there is no way to produce a Result<A, E> without an E value. NonEmptyVecF also lacks an instance because a non-empty vector cannot be empty by definition.
VecF requires the alloc or std feature.
Example
use karpal_std::prelude::*;
// zero() for Option is None
let empty: Option<i32> = OptionF::zero();
assert_eq!(empty, None);
// zero() for Vec is an empty vector
let empty_vec: Vec<i32> = VecF::zero();
assert_eq!(empty_vec, Vec::<i32>::new());
// Left identity: alt(zero(), a) == a
let a = Some(10);
assert_eq!(OptionF::alt(OptionF::zero(), a), a);
// Right identity: alt(a, zero()) == a
assert_eq!(OptionF::alt(a, OptionF::zero()), a);
Alternative
Alternative
Signature
pub trait Alternative: Applicative + Plus {}
impl<F: Applicative + Plus> Alternative for F {}
Alternative is a marker trait that combines Applicative and Plus. It introduces no new methods — any type that implements both Applicative and Plus automatically implements Alternative via the blanket impl.
Laws
Alternative inherits all laws from Alt, Plus, and Applicative, and adds two of its own:
Instances
| Type constructor | Notes |
|---|---|
OptionF | Implements both Applicative and Plus, so Alternative is provided automatically |
VecF | Implements both Applicative and Plus, so Alternative is provided automatically (requires alloc or std) |
Example
use karpal_std::prelude::*;
// Alternative lets you combine choice (Alt/Plus) with
// applicative computation (Applicative).
// Distributivity: ap(alt(f, g), x) == alt(ap(f, x), ap(g, x))
let f: Option<fn(i32) -> i32> = Some(|a| a + 1);
let g: Option<fn(i32) -> i32> = Some(|a| a * 2);
let x = Some(10);
let left = OptionF::ap(OptionF::alt(f, g), x);
let right = OptionF::alt(OptionF::ap(f, x), OptionF::ap(g, x));
assert_eq!(left, right); // Both are Some(11)
// Annihilation: ap(zero(), x) == zero()
let no_fn: Option<fn(i32) -> i32> = OptionF::zero();
let result = OptionF::ap(no_fn, Some(5));
assert_eq!(result, None);
See Also
- Functor Family — the Functor → Apply → Applicative → Chain → Monad branch that Alt builds upon.
- Semigroup & Monoid — the value-level analogue: Semigroup provides an associative
combine, Monoid adds anemptyidentity, mirroring the Alt/Plus relationship at the functor level. - Foldable & Traversable — traits for collapsing and sequencing containers, which compose naturally with Alt and Plus.