pub trait MonadPlus: Monad + Alternative { }Expand description
A type class for monads that also support choice, combining Monad
and Alternative.
class (Monad m, Alternative m) => MonadPlus m
MonadPlus has no members of its own. It specifies that the type
constructor supports both monadic sequencing (bind, pure) and
choice with an identity element (alt, empty).
§Laws
A lawful MonadPlus must satisfy:
-
Distributivity: binding over a choice distributes:
bind(alt(x, y), f) == alt(bind(x, f), bind(y, f))
The following property also holds for any Monad + Alternative:
-
Left zero: binding on the identity element yields the identity element:
bind(empty(), f) == empty()
§Examples
Distributivity law for Vec:
use fp_library::{
brands::*,
functions::explicit::*,
};
let x: Vec<i32> = vec![1, 2];
let y: Vec<i32> = vec![3, 4];
let f = |n: i32| vec![n * 10, n * 100];
assert_eq!(
bind::<VecBrand, _, _, _, _>(alt::<VecBrand, _, _, _>(x.clone(), y.clone()), f),
alt::<VecBrand, _, _, _>(
bind::<VecBrand, _, _, _, _>(x, f),
bind::<VecBrand, _, _, _, _>(y, f)
),
);Left-zero law for Vec:
use fp_library::{
brands::*,
functions::{
explicit::bind,
*,
},
};
let f = |n: i32| vec![n * 2];
assert_eq!(
bind::<VecBrand, _, _, _, _>(plus_empty::<VecBrand, i32>(), f),
plus_empty::<VecBrand, i32>(),
);§Implementors
The blanket implementation applies to every brand with both Monad
and Alternative. The following brands are known to be lawful
(satisfying distributivity and left zero):
Note that OptionBrand acquires the
trait via the blanket impl but does not satisfy the distributivity
law, because alt for Option picks the first Some and discards
the second branch entirely.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.