#[fp_macros::document_module]
mod inner {
use {
crate::{
Apply,
brands::{
OptionBrand,
VecBrand,
},
classes::*,
dispatch::Ref,
impl_kind,
kinds::*,
},
core::ops::ControlFlow,
fp_macros::*,
};
impl_kind! {
for VecBrand {
type Of<'a, A: 'a>: 'a = Vec<A>;
}
}
impl VecBrand {
#[document_signature]
#[document_type_parameters("The type of the elements in the vector.")]
#[document_parameters(
"A value to prepend to the vector.",
"A vector to prepend the value to."
)]
#[document_returns(
"A new vector consisting of the `head` element prepended to the `tail` vector."
)]
#[document_examples]
pub fn construct<A>(
head: A,
tail: Vec<A>,
) -> Vec<A>
where
A: Clone, {
[vec![head], tail].concat()
}
#[document_signature]
#[document_type_parameters("The type of the elements in the vector.")]
#[document_parameters("The vector slice to deconstruct.")]
#[document_returns(
"An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
)]
#[document_examples]
pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
where
A: Clone, {
match slice {
[] => None,
[head, tail @ ..] => Some((head.clone(), tail.to_vec())),
}
}
}
impl Functor for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the vector.",
"The type of the elements in the resulting vector."
)]
#[document_parameters("The function to apply to each element.", "The vector to map over.")]
#[document_returns("A new vector containing the results of applying the function.")]
#[document_examples]
fn map<'a, A: 'a, B: 'a>(
func: impl Fn(A) -> B + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.into_iter().map(func).collect()
}
}
impl Lift for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the first vector.",
"The type of the elements in the second vector.",
"The type of the elements in the resulting vector."
)]
#[document_parameters(
"The binary function to apply.",
"The first vector.",
"The second vector."
)]
#[document_returns(
"A new vector containing the results of applying the function to all pairs of elements."
)]
#[document_examples]
fn lift2<'a, A, B, C>(
func: impl Fn(A, B) -> C + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
where
A: Clone + 'a,
B: Clone + 'a,
C: 'a, {
fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
}
}
impl Pointed for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
#[document_parameters("The value to wrap.")]
#[document_returns("A vector containing the single value.")]
#[document_examples]
fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
vec![a]
}
}
impl ApplyFirst for VecBrand {}
impl ApplySecond for VecBrand {}
impl Semiapplicative for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the cloneable function wrapper.",
"The type of the input values.",
"The type of the output values."
)]
#[document_parameters(
"The vector containing the functions.",
"The vector containing the values."
)]
#[document_returns(
"A new vector containing the results of applying each function to each value."
)]
#[document_examples]
fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
}
}
impl Semimonad for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the input vector.",
"The type of the elements in the output vector."
)]
#[document_parameters(
"The first vector.",
"The function to apply to each element, returning a vector."
)]
#[document_returns("A new vector containing the flattened results.")]
#[document_examples]
fn bind<'a, A: 'a, B: 'a>(
ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
ma.into_iter().flat_map(func).collect()
}
}
impl Alt for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters("The first vector.", "The second vector.")]
#[document_returns("The concatenated vector.")]
#[document_examples]
fn alt<'a, A: 'a>(
fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
let mut result = fa1;
result.extend(fa2);
result
}
}
impl RefAlt for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters("The first vector.", "The second vector.")]
#[document_returns("A new vector containing cloned elements from both inputs.")]
#[document_examples]
fn ref_alt<'a, A: 'a + Clone>(
fa1: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
fa2: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
fa1.iter().chain(fa2.iter()).cloned().collect()
}
}
impl Plus for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_returns("An empty vector.")]
#[document_examples]
fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
Vec::new()
}
}
impl Foldable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function to use.",
"The type of the elements in the vector.",
"The type of the accumulator."
)]
#[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
#[document_returns("The final accumulator value.")]
#[document_examples]
fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
func: impl Fn(A, B) -> B + 'a,
initial: B,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> B
where
FnBrand: CloneFn + 'a, {
fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function to use.",
"The type of the elements in the vector.",
"The type of the accumulator."
)]
#[document_parameters(
"The function to apply to the accumulator and each element.",
"The initial value of the accumulator.",
"The vector to fold."
)]
#[document_returns("The final accumulator value.")]
#[document_examples]
fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
func: impl Fn(B, A) -> B + 'a,
initial: B,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> B
where
FnBrand: CloneFn + 'a, {
fa.into_iter().fold(initial, func)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function to use.",
"The type of the elements in the vector.",
"The type of the monoid."
)]
#[document_parameters("The mapping function.", "The vector to fold.")]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
func: impl Fn(A) -> M + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M
where
M: Monoid + 'a,
FnBrand: CloneFn + 'a, {
fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
}
}
impl Traversable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the traversable structure.",
"The type of the elements in the resulting traversable structure.",
"The applicative context."
)]
#[document_parameters(
"The function to apply to each element, returning a value in an applicative context.",
"The vector to traverse."
)]
#[document_returns("The vector wrapped in the applicative context.")]
#[document_examples]
fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
where
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
let len = ta.len();
ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
F::lift2(
|mut v, b| {
v.push(b);
v
},
acc,
func(x),
)
})
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the traversable structure.",
"The applicative context."
)]
#[document_parameters("The vector containing the applicative values.")]
#[document_returns("The vector wrapped in the applicative context.")]
#[document_examples]
fn sequence<'a, A: 'a + Clone, F: Applicative>(
ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
where
Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
let len = ta.len();
ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
F::lift2(
|mut v, a| {
v.push(a);
v
},
acc,
x,
)
})
}
}
impl WithIndex for VecBrand {
type Index = usize;
}
impl FunctorWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the vector.",
"The type of the elements in the resulting vector."
)]
#[document_parameters(
"The function to apply to each element and its index.",
"The vector to map over."
)]
#[document_returns("A new vector containing the results of applying the function.")]
#[document_examples]
fn map_with_index<'a, A: 'a, B: 'a>(
f: impl Fn(usize, A) -> B + 'a,
fa: Vec<A>,
) -> Vec<B> {
fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
}
}
impl FoldableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function to use.",
"The type of the elements in the vector.",
"The monoid type."
)]
#[document_parameters(
"The function to apply to each element and its index.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
f: impl Fn(usize, A) -> R + 'a,
fa: Vec<A>,
) -> R
where
FnBrand: LiftFn + 'a, {
fa.into_iter()
.enumerate()
.map(|(i, a)| f(i, a))
.fold(R::empty(), |acc, x| R::append(acc, x))
}
}
impl TraversableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the vector.",
"The type of the elements in the resulting vector.",
"The applicative context."
)]
#[document_parameters(
"The function to apply to each element and its index, returning a value in an applicative context.",
"The vector to traverse."
)]
#[document_returns("The vector wrapped in the applicative context.")]
#[document_examples]
fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
ta: Vec<A>,
) -> M::Of<'a, Vec<B>> {
let len = ta.len();
ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
M::lift2(
|mut v, b| {
v.push(b);
v
},
acc,
f(i, x),
)
})
}
}
#[document_type_parameters("The type of the elements in the vector.")]
impl<A: Clone> Semigroup for Vec<A> {
#[document_signature]
#[document_parameters("The first vector.", "The second vector.")]
#[document_returns("The concatenated vector.")]
#[document_examples]
fn append(
a: Self,
b: Self,
) -> Self {
[a, b].concat()
}
}
#[document_type_parameters("The type of the elements in the vector.")]
impl<A: Clone> Monoid for Vec<A> {
#[document_signature]
#[document_returns("An empty vector.")]
#[document_examples]
fn empty() -> Self {
Vec::new()
}
}
impl VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each element. Must be `Send + Sync`.",
"The vector to map over."
)]
#[document_returns("A new vector containing the mapped elements.")]
#[document_examples]
pub fn par_map<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(A) -> B + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<B> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().map(f).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().map(f).collect()
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters("The vector of options.")]
#[document_returns("A new vector containing the unwrapped `Some` values.")]
#[document_examples]
pub fn par_compact<'a, A: 'a + Send>(fa: Vec<Option<A>>) -> Vec<A> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().flatten().collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().flatten().collect()
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The error type.",
"The success type."
)]
#[document_parameters("The vector of results.")]
#[document_returns(
"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
)]
#[document_examples]
pub fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
fa: Vec<Result<O, E>>
) -> (Vec<E>, Vec<O>) {
#[cfg(feature = "rayon")]
{
use rayon::{
iter::Either,
prelude::*,
};
fa.into_par_iter().partition_map(|r| match r {
Ok(o) => Either::Right(o),
Err(e) => Either::Left(e),
})
}
#[cfg(not(feature = "rayon"))]
{
let mut errs = Vec::new();
let mut oks = Vec::new();
for result in fa {
match result {
Ok(o) => oks.push(o),
Err(e) => errs.push(e),
}
}
(errs, oks)
}
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply. Must be `Send + Sync`.",
"The vector to filter and map."
)]
#[document_returns("A new vector containing the `Some` results of applying `f`.")]
#[document_examples]
pub fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<B> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().filter_map(f).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().filter_map(f).collect()
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
#[document_returns("A new vector containing only the elements satisfying `f`.")]
#[document_examples]
pub fn par_filter<'a, A: 'a + Send>(
f: impl Fn(&A) -> bool + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<A> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().filter(|a| f(a)).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().filter(|a| f(a)).collect()
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The element type.",
"The monoid type."
)]
#[document_parameters(
"The function mapping each element to a monoid value. Must be `Send + Sync`.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
pub fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
f: impl Fn(A) -> M + Send + Sync + 'a,
fa: Vec<A>,
) -> M {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().map(f).reduce(M::empty, |acc, m| M::append(acc, m))
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().map(f).fold(M::empty(), |acc, m| M::append(acc, m))
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each index and element. Must be `Send + Sync`.",
"The vector to map over."
)]
#[document_returns("A new vector containing the mapped elements.")]
#[document_examples]
pub fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(usize, A) -> B + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<B> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The element type.",
"The monoid type."
)]
#[document_parameters(
"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
pub fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
f: impl Fn(usize, A) -> M + Send + Sync + 'a,
fa: Vec<A>,
) -> M {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter()
.enumerate()
.map(|(i, a)| f(i, a))
.reduce(M::empty, |acc, m| M::append(acc, m))
}
#[cfg(not(feature = "rayon"))]
fa.into_iter()
.enumerate()
.map(|(i, a)| f(i, a))
.fold(M::empty(), |acc, m| M::append(acc, m))
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each index and element. Must be `Send + Sync`.",
"The vector to filter and map."
)]
#[document_returns("A new vector containing the `Some` results of applying `f`.")]
#[document_examples]
pub fn par_filter_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(usize, A) -> Option<B> + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<B> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters(
"The predicate receiving the index and a reference to the element. Must be `Send + Sync`.",
"The vector to filter."
)]
#[document_returns("A new vector containing only the elements satisfying `f`.")]
#[document_examples]
pub fn par_filter_with_index<'a, A: 'a + Send>(
f: impl Fn(usize, &A) -> bool + Send + Sync + 'a,
fa: Vec<A>,
) -> Vec<A> {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.into_par_iter().enumerate().filter(|(i, a)| f(*i, a)).map(|(_, a)| a).collect()
}
#[cfg(not(feature = "rayon"))]
fa.into_iter().enumerate().filter(|(i, a)| f(*i, a)).map(|(_, a)| a).collect()
}
}
impl ParFunctor for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each element. Must be `Send + Sync`.",
"The vector to map over."
)]
#[document_returns("A new vector containing the mapped elements.")]
#[document_examples]
fn par_map<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(A) -> B + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
VecBrand::par_map(f, fa)
}
}
impl ParCompactable for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters("The vector of options.")]
#[document_returns("A new vector containing the unwrapped `Some` values.")]
#[document_examples]
fn par_compact<'a, A: 'a + Send>(
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
'a,
Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
>)
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
VecBrand::par_compact(fa)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The error type.",
"The success type."
)]
#[document_parameters("The vector of results.")]
#[document_returns(
"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
)]
#[document_examples]
fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
) -> (
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
) {
VecBrand::par_separate(fa)
}
}
impl ParFilterable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply. Must be `Send + Sync`.",
"The vector to filter and map."
)]
#[document_returns("A new vector containing the `Some` results of applying `f`.")]
#[document_examples]
fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
VecBrand::par_filter_map(f, fa)
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
#[document_returns("A new vector containing only the elements satisfying `f`.")]
#[document_examples]
fn par_filter<'a, A: 'a + Send>(
f: impl Fn(&A) -> bool + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
VecBrand::par_filter(f, fa)
}
}
impl ParFoldable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The element type.",
"The monoid type."
)]
#[document_parameters(
"The function mapping each element to a monoid value. Must be `Send + Sync`.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
f: impl Fn(A) -> M + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M {
VecBrand::par_fold_map(f, fa)
}
}
impl ParFunctorWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each index and element. Must be `Send + Sync`.",
"The vector to map over."
)]
#[document_returns("A new vector containing the mapped elements.")]
#[document_examples]
fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(usize, A) -> B + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
where
usize: Send + Sync + Copy + 'a, {
VecBrand::par_map_with_index(f, fa)
}
}
impl ParFoldableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The element type.",
"The monoid type."
)]
#[document_parameters(
"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
f: impl Fn(usize, A) -> M + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M
where
usize: Send + Sync + Copy + 'a, {
VecBrand::par_fold_map_with_index(f, fa)
}
}
impl Compactable for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters("The vector of options.")]
#[document_returns("The flattened vector.")]
#[document_examples]
fn compact<'a, A: 'a>(
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
'a,
Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
>)
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
fa.into_iter().flatten().collect()
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the error value.",
"The type of the success value."
)]
#[document_parameters("The vector of results.")]
#[document_returns("A pair of vectors.")]
#[document_examples]
fn separate<'a, E: 'a, O: 'a>(
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
) -> (
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
) {
let mut oks = Vec::new();
let mut errs = Vec::new();
for result in fa {
match result {
Ok(o) => oks.push(o),
Err(e) => errs.push(e),
}
}
(errs, oks)
}
}
impl RefCompactable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the [`Option`]. Must be [`Clone`] because elements are extracted from a borrowed container."
)]
#[document_parameters("A reference to the vector containing [`Option`] values.")]
#[document_returns(
"A new vector containing only the cloned values from the [`Some`] variants."
)]
#[document_examples]
fn ref_compact<'a, A: 'a + Clone>(
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<A>>)
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
fa.iter().filter_map(|opt| opt.as_ref().cloned()).collect()
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the error values. Must be [`Clone`] because elements are extracted from a borrowed container.",
"The type of the success values. Must be [`Clone`] because elements are extracted from a borrowed container."
)]
#[document_parameters("A reference to the vector containing [`Result`] values.")]
#[document_returns(
"A pair of vectors: the first containing the cloned [`Err`] values, and the second containing the cloned [`Ok`] values."
)]
#[document_examples]
fn ref_separate<'a, E: 'a + Clone, O: 'a + Clone>(
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
) -> (
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
) {
let mut errs = Vec::new();
let mut oks = Vec::new();
for result in fa.iter() {
match result {
Ok(o) => oks.push(o.clone()),
Err(e) => errs.push(e.clone()),
}
}
(errs, oks)
}
}
impl Filterable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input value.",
"The type of the error value.",
"The type of the success value."
)]
#[document_parameters("The function to apply.", "The vector to partition.")]
#[document_returns("A pair of vectors.")]
#[document_examples]
fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
func: impl Fn(A) -> Result<O, E> + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> (
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
) {
let mut oks = Vec::new();
let mut errs = Vec::new();
for a in fa {
match func(a) {
Ok(o) => oks.push(o),
Err(e) => errs.push(e),
}
}
(errs, oks)
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters("The predicate.", "The vector to partition.")]
#[document_returns("A pair of vectors.")]
#[document_examples]
fn partition<'a, A: 'a + Clone>(
func: impl Fn(A) -> bool + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> (
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) {
let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
fa.into_iter().partition(|a| func(a.clone()));
(not_satisfied, satisfied)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input value.",
"The type of the result of applying the function."
)]
#[document_parameters("The function to apply.", "The vector to filter and map.")]
#[document_returns("The filtered and mapped vector.")]
#[document_examples]
fn filter_map<'a, A: 'a, B: 'a>(
func: impl Fn(A) -> Option<B> + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.into_iter().filter_map(func).collect()
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters("The predicate.", "The vector to filter.")]
#[document_returns("The filtered vector.")]
#[document_examples]
fn filter<'a, A: 'a + Clone>(
func: impl Fn(A) -> bool + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
fa.into_iter().filter(|a| func(a.clone())).collect()
}
}
impl FilterableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input value.",
"The type of the error value.",
"The type of the success value."
)]
#[document_parameters(
"The function to apply to each element and its index.",
"The vector to partition."
)]
#[document_returns("A pair of vectors.")]
#[document_examples]
fn partition_map_with_index<'a, A: 'a, E: 'a, O: 'a>(
func: impl Fn(usize, A) -> Result<O, E> + 'a,
fa: Vec<A>,
) -> (Vec<E>, Vec<O>) {
let mut oks = Vec::new();
let mut errs = Vec::new();
for (i, a) in fa.into_iter().enumerate() {
match func(i, a) {
Ok(o) => oks.push(o),
Err(e) => errs.push(e),
}
}
(errs, oks)
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters(
"The predicate receiving the index and element.",
"The vector to partition."
)]
#[document_returns("A pair of vectors.")]
#[document_examples]
fn partition_with_index<'a, A: 'a + Clone>(
func: impl Fn(usize, A) -> bool + 'a,
fa: Vec<A>,
) -> (Vec<A>, Vec<A>) {
let mut satisfied = Vec::new();
let mut not_satisfied = Vec::new();
for (i, a) in fa.into_iter().enumerate() {
if func(i, a.clone()) {
satisfied.push(a);
} else {
not_satisfied.push(a);
}
}
(not_satisfied, satisfied)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input value.",
"The type of the result of applying the function."
)]
#[document_parameters(
"The function to apply to each element and its index.",
"The vector to filter and map."
)]
#[document_returns("The filtered and mapped vector.")]
#[document_examples]
fn filter_map_with_index<'a, A: 'a, B: 'a>(
func: impl Fn(usize, A) -> Option<B> + 'a,
fa: Vec<A>,
) -> Vec<B> {
fa.into_iter().enumerate().filter_map(|(i, a)| func(i, a)).collect()
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
#[document_parameters(
"The predicate receiving the index and element.",
"The vector to filter."
)]
#[document_returns("The filtered vector.")]
#[document_examples]
fn filter_with_index<'a, A: 'a + Clone>(
func: impl Fn(usize, A) -> bool + 'a,
fa: Vec<A>,
) -> Vec<A> {
fa.into_iter()
.enumerate()
.filter(|(i, a)| func(*i, a.clone()))
.map(|(_, a)| a)
.collect()
}
}
impl ParFilterableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The input element type.",
"The output element type."
)]
#[document_parameters(
"The function to apply to each index and element. Must be `Send + Sync`.",
"The vector to filter and map."
)]
#[document_returns("A new vector containing the `Some` results of applying `f`.")]
#[document_examples]
fn par_filter_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
f: impl Fn(usize, A) -> Option<B> + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
where
usize: Send + Sync + Copy + 'a, {
VecBrand::par_filter_map_with_index(f, fa)
}
#[document_signature]
#[document_type_parameters("The lifetime of the elements.", "The element type.")]
#[document_parameters(
"The predicate receiving the index and a reference to the element. Must be `Send + Sync`.",
"The vector to filter."
)]
#[document_returns("A new vector containing only the elements satisfying `f`.")]
#[document_examples]
fn par_filter_with_index<'a, A: 'a + Send>(
f: impl Fn(usize, &A) -> bool + Send + Sync + 'a,
fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
where
usize: Send + Sync + Copy + 'a, {
VecBrand::par_filter_with_index(f, fa)
}
}
impl Witherable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The applicative context.",
"The type of the input value.",
"The type of the error value.",
"The type of the success value."
)]
#[document_parameters("The function to apply.", "The vector to partition.")]
#[document_returns("The partitioned vector wrapped in the applicative context.")]
#[document_examples]
fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
+ 'a,
ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
'a,
(
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
),
>)
where
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
M::lift2(
|mut pair, res| {
match res {
Ok(o) => pair.1.push(o),
Err(e) => pair.0.push(e),
}
pair
},
acc,
func(x),
)
})
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The applicative context.",
"The type of the elements in the input structure.",
"The type of the result of applying the function."
)]
#[document_parameters(
"The function to apply to each element, returning an `Option` in an applicative context.",
"The vector to filter and map."
)]
#[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
#[document_examples]
fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
'a,
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
>)
where
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
M::lift2(
|mut v, opt_b| {
if let Some(b) = opt_b {
v.push(b);
}
v
},
acc,
func(x),
)
})
}
}
impl Extend for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The type of the elements in the vector.",
"The result type of the extension function."
)]
#[document_parameters(
"The function that consumes a suffix vector and produces a value.",
"The vector to extend over."
)]
#[document_returns(
"A new vector containing the results of applying the function to each suffix."
)]
#[document_examples]
fn extend<'a, A: 'a + Clone, B: 'a>(
f: impl Fn(Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> B + 'a,
wa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
(0 .. wa.len()).map(|i| f(wa.get(i ..).unwrap_or_default().to_vec())).collect()
}
}
impl MonadRec for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the computation.",
"The type of the initial value and loop state.",
"The type of the result."
)]
#[document_parameters("The step function.", "The initial value.")]
#[document_returns("A vector of all completed results.")]
#[document_examples]
fn tail_rec_m<'a, A: 'a, B: 'a>(
func: impl Fn(
A,
)
-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
+ 'a,
initial: A,
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
let mut done: Vec<B> = Vec::new();
let mut pending: Vec<A> = vec![initial];
while !pending.is_empty() {
let mut next_pending: Vec<A> = Vec::new();
for a in pending {
for step in func(a) {
match step {
ControlFlow::Continue(next) => next_pending.push(next),
ControlFlow::Break(b) => done.push(b),
}
}
}
pending = next_pending;
}
done
}
}
impl RefFunctor for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the elements in the vector.",
"The type of the elements in the resulting vector."
)]
#[document_parameters(
"The function to apply to each element reference.",
"The vector to map over."
)]
#[document_returns("A new vector containing the results.")]
#[document_examples]
fn ref_map<'a, A: 'a, B: 'a>(
func: impl Fn(&A) -> B + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.iter().map(func).collect()
}
}
impl RefFoldable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function wrapper.",
"The type of the elements.",
"The monoid type."
)]
#[document_parameters(
"The function to map each element reference to a monoid.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
func: impl Fn(&A) -> M + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M
where
FnBrand: LiftFn + 'a,
M: Monoid + 'a, {
fa.iter().fold(Monoid::empty(), |acc, a| Semigroup::append(acc, func(a)))
}
}
impl RefFilterable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input elements.",
"The type of the output elements."
)]
#[document_parameters("The filter-map function.", "The vector to filter.")]
#[document_returns("The filtered vector.")]
#[document_examples]
fn ref_filter_map<'a, A: 'a, B: 'a>(
func: impl Fn(&A) -> Option<B> + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.iter().filter_map(func).collect()
}
}
impl RefTraversable for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function wrapper.",
"The type of the input elements.",
"The type of the output elements.",
"The applicative functor brand."
)]
#[document_parameters(
"The function to apply to each element reference.",
"The vector to traverse."
)]
#[document_returns("The combined result in the applicative context.")]
#[document_examples]
fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
where
FnBrand: LiftFn + 'a,
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
let len = ta.len();
ta.iter().fold(
F::pure::<Vec<B>>(Vec::with_capacity(len)),
|acc: Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Vec<B>>), a| {
F::lift2(
|mut v: Vec<B>, b: B| {
v.push(b);
v
},
acc,
func(a),
)
},
)
}
}
impl RefWitherable for VecBrand {}
impl RefFunctorWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input elements.",
"The type of the output elements."
)]
#[document_parameters("The function to apply.", "The vector to map over.")]
#[document_returns("The mapped vector.")]
#[document_examples]
fn ref_map_with_index<'a, A: 'a, B: 'a>(
func: impl Fn(usize, &A) -> B + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.iter().enumerate().map(|(i, a)| func(i, a)).collect()
}
}
impl RefFoldableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The brand of the cloneable function to use.",
"The type of the elements.",
"The monoid type."
)]
#[document_parameters(
"The function to map each (index, element reference) pair.",
"The vector to fold."
)]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
func: impl Fn(usize, &A) -> R + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> R
where
FnBrand: LiftFn + 'a, {
fa.iter()
.enumerate()
.fold(Monoid::empty(), |acc, (i, a)| Semigroup::append(acc, func(i, a)))
}
}
impl RefFilterableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input elements.",
"The type of the output elements."
)]
#[document_parameters("The filter-map function.", "The vector to filter.")]
#[document_returns("The filtered vector.")]
#[document_examples]
fn ref_filter_map_with_index<'a, A: 'a, B: 'a>(
func: impl Fn(usize, &A) -> Option<B> + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.iter().enumerate().filter_map(|(i, a)| func(i, a)).collect()
}
}
impl RefTraversableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the elements.",
"The type of the input elements.",
"The type of the output elements.",
"The applicative functor brand."
)]
#[document_parameters("The function to apply.", "The vector to traverse.")]
#[document_returns("The combined result in the applicative context.")]
#[document_examples]
fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
f: impl Fn(usize, &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
where
Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
let len = ta.len();
ta.iter().enumerate().fold(
M::pure::<Vec<B>>(Vec::with_capacity(len)),
|acc: Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Vec<B>>), (i, a)| {
M::lift2(
|mut v: Vec<B>, b: B| {
v.push(b);
v
},
acc,
f(i, a),
)
},
)
}
}
impl RefPointed for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime of the value.", "The type of the value.")]
#[document_parameters("The reference to the value to wrap.")]
#[document_returns("A singleton vector containing a clone of the value.")]
#[document_examples]
fn ref_pure<'a, A: Clone + 'a>(
a: &A
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
vec![a.clone()]
}
}
impl RefLift for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The type of the first input.",
"The type of the second input.",
"The type of the output."
)]
#[document_parameters(
"The binary function receiving references.",
"The first vector.",
"The second vector."
)]
#[document_returns("A new vector with the combined results.")]
#[document_examples]
fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
func: impl Fn(&A, &B) -> C + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
let func = &func;
fa.iter().flat_map(|a| fb.iter().map(move |b| func(a, b))).collect()
}
}
impl RefSemiapplicative for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the cloneable function wrapper.",
"The type of the input values.",
"The type of the output values."
)]
#[document_parameters(
"The vector containing the by-ref functions.",
"The vector containing the values."
)]
#[document_returns("A new vector with each function applied to each value by reference.")]
#[document_examples]
fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
ff.iter().flat_map(|f| fa.iter().map(move |a| (**f)(a))).collect()
}
}
impl RefSemimonad for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The type of the input values.",
"The type of the output values."
)]
#[document_parameters(
"The input vector.",
"The function to apply to each element by reference."
)]
#[document_returns("A new vector with the results flattened.")]
#[document_examples]
fn ref_bind<'a, A: 'a, B: 'a>(
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
fa.iter().flat_map(f).collect()
}
}
impl ParRefFunctor for VecBrand {
#[document_signature]
#[document_type_parameters(
"The lifetime.",
"The input element type.",
"The output element type."
)]
#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
#[document_returns("A new vector with mapped elements.")]
#[document_examples]
fn par_ref_map<'a, A: Send + Sync + 'a, B: Send + 'a>(
f: impl Fn(&A) -> B + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter().map(f).collect()
}
#[cfg(not(feature = "rayon"))]
fa.iter().map(f).collect()
}
}
impl ParRefFoldable for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime.", "The element type.", "The monoid type.")]
#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn par_ref_fold_map<'a, A: Send + Sync + 'a, M: Monoid + Send + 'a>(
f: impl Fn(&A) -> M + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter().map(f).reduce(Monoid::empty, Semigroup::append)
}
#[cfg(not(feature = "rayon"))]
fa.iter().map(f).fold(Monoid::empty(), |acc, m| Semigroup::append(acc, m))
}
}
impl ParRefFilterable for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
#[document_returns("A new vector with filtered and mapped elements.")]
#[document_examples]
fn par_ref_filter_map<'a, A: Send + Sync + 'a, B: Send + 'a>(
f: impl Fn(&A) -> Option<B> + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter().filter_map(f).collect()
}
#[cfg(not(feature = "rayon"))]
fa.iter().filter_map(f).collect()
}
}
impl ParRefFunctorWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
#[document_returns("A new vector with mapped elements.")]
#[document_examples]
fn par_ref_map_with_index<'a, A: Send + Sync + 'a, B: Send + 'a>(
f: impl Fn(usize, &A) -> B + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
}
#[cfg(not(feature = "rayon"))]
fa.iter().enumerate().map(|(i, a)| f(i, a)).collect()
}
}
impl ParRefFoldableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime.", "The element type.", "The monoid type.")]
#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn par_ref_fold_map_with_index<'a, A: Send + Sync + 'a, M: Monoid + Send + 'a>(
f: impl Fn(usize, &A) -> M + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> M {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter()
.enumerate()
.map(|(i, a)| f(i, a))
.reduce(Monoid::empty, Semigroup::append)
}
#[cfg(not(feature = "rayon"))]
fa.iter()
.enumerate()
.map(|(i, a)| f(i, a))
.fold(Monoid::empty(), |acc, m| Semigroup::append(acc, m))
}
}
impl ParRefFilterableWithIndex for VecBrand {
#[document_signature]
#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
#[document_returns("A new vector with filtered and mapped elements.")]
#[document_examples]
fn par_ref_filter_map_with_index<'a, A: Send + Sync + 'a, B: Send + 'a>(
f: impl Fn(usize, &A) -> Option<B> + Send + Sync + 'a,
fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
#[cfg(feature = "rayon")]
{
use rayon::prelude::*;
fa.par_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
}
#[cfg(not(feature = "rayon"))]
fa.iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
}
}
}
#[cfg(test)]
mod tests {
use {
crate::{
brands::*,
classes::*,
functions::*,
},
quickcheck_macros::quickcheck,
};
#[quickcheck]
fn functor_identity(x: Vec<i32>) -> bool {
explicit::map::<VecBrand, _, _, _, _>(identity, x.clone()) == x
}
#[quickcheck]
fn functor_composition(x: Vec<i32>) -> bool {
let f = |x: i32| x.wrapping_add(1);
let g = |x: i32| x.wrapping_mul(2);
explicit::map::<VecBrand, _, _, _, _>(compose(f, g), x.clone())
== explicit::map::<VecBrand, _, _, _, _>(f, explicit::map::<VecBrand, _, _, _, _>(g, x))
}
#[quickcheck]
fn applicative_identity(v: Vec<i32>) -> bool {
apply(pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(identity)), v.clone()) == v
}
#[quickcheck]
fn applicative_homomorphism(x: i32) -> bool {
let f = |x: i32| x.wrapping_mul(2);
apply(pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(f)), pure::<VecBrand, _>(x))
== pure::<VecBrand, _>(f(x))
}
#[quickcheck]
fn applicative_composition(
w: Vec<i32>,
u_seeds: Vec<i32>,
v_seeds: Vec<i32>,
) -> bool {
let u_fns: Vec<_> = u_seeds
.iter()
.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_add(i)))
.collect();
let v_fns: Vec<_> = v_seeds
.iter()
.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_mul(i)))
.collect();
let vw = apply(v_fns.clone(), w.clone());
let rhs = apply(u_fns.clone(), vw);
let uv_fns: Vec<_> = u_fns
.iter()
.flat_map(|uf| {
v_fns.iter().map(move |vf| {
let uf = uf.clone();
let vf = vf.clone();
<RcFnBrand as LiftFn>::new(move |x| uf(vf(x)))
})
})
.collect();
let lhs = apply(uv_fns, w);
lhs == rhs
}
#[quickcheck]
fn applicative_interchange(y: i32) -> bool {
let f = |x: i32| x.wrapping_mul(2);
let u = vec![<RcFnBrand as LiftFn>::new(f)];
let lhs = apply(u.clone(), pure::<VecBrand, _>(y));
let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
let rhs = apply(pure::<VecBrand, _>(rhs_fn), u);
lhs == rhs
}
#[quickcheck]
fn semigroup_associativity(
a: Vec<i32>,
b: Vec<i32>,
c: Vec<i32>,
) -> bool {
append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
}
#[quickcheck]
fn monoid_left_identity(a: Vec<i32>) -> bool {
append(empty::<Vec<i32>>(), a.clone()) == a
}
#[quickcheck]
fn monoid_right_identity(a: Vec<i32>) -> bool {
append(a.clone(), empty::<Vec<i32>>()) == a
}
#[quickcheck]
fn monad_left_identity(a: i32) -> bool {
let f = |x: i32| vec![x.wrapping_mul(2)];
explicit::bind::<VecBrand, _, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
}
#[quickcheck]
fn monad_right_identity(m: Vec<i32>) -> bool {
explicit::bind::<VecBrand, _, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
}
#[quickcheck]
fn monad_associativity(m: Vec<i32>) -> bool {
let f = |x: i32| vec![x.wrapping_mul(2)];
let g = |x: i32| vec![x.wrapping_add(1)];
explicit::bind::<VecBrand, _, _, _, _>(
explicit::bind::<VecBrand, _, _, _, _>(m.clone(), f),
g,
) == explicit::bind::<VecBrand, _, _, _, _>(m, |x| {
explicit::bind::<VecBrand, _, _, _, _>(f(x), g)
})
}
#[test]
fn map_empty() {
assert_eq!(
explicit::map::<VecBrand, _, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
vec![] as Vec<i32>
);
}
#[test]
fn bind_empty() {
assert_eq!(
explicit::bind::<VecBrand, _, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
vec![] as Vec<i32>
);
}
#[test]
fn bind_returning_empty() {
assert_eq!(
explicit::bind::<VecBrand, _, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
vec![] as Vec<i32>
);
}
#[test]
fn fold_right_empty() {
assert_eq!(
crate::functions::explicit::fold_right::<RcFnBrand, VecBrand, _, _, _, _>(
|x: i32, acc| x + acc,
0,
vec![]
),
0
);
}
#[test]
fn fold_left_empty() {
assert_eq!(
crate::functions::explicit::fold_left::<RcFnBrand, VecBrand, _, _, _, _>(
|acc, x: i32| acc + x,
0,
vec![]
),
0
);
}
#[test]
fn traverse_empty() {
use crate::brands::OptionBrand;
assert_eq!(
crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
|x: i32| Some(x + 1),
vec![]
),
Some(vec![])
);
}
#[test]
fn traverse_returning_empty() {
use crate::brands::OptionBrand;
assert_eq!(
crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
|_: i32| None::<i32>,
vec![1, 2, 3]
),
None
);
}
#[test]
fn construct_empty_tail() {
assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
}
#[test]
fn deconstruct_empty() {
assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
}
#[test]
fn par_map_basic() {
let v = vec![1, 2, 3];
let result: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v);
assert_eq!(result, vec![2, 4, 6]);
}
#[test]
fn par_filter_basic() {
let v = vec![1, 2, 3, 4, 5];
let result: Vec<i32> = par_filter::<VecBrand, _>(|x: &i32| x % 2 == 0, v);
assert_eq!(result, vec![2, 4]);
}
#[test]
fn par_filter_map_basic() {
let v = vec![1, 2, 3, 4, 5];
let result: Vec<i32> = par_filter_map::<VecBrand, _, _>(
|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
v,
);
assert_eq!(result, vec![20, 40]);
}
#[test]
fn par_compact_basic() {
let v = vec![Some(1), None, Some(3), None, Some(5)];
let result: Vec<i32> = par_compact::<VecBrand, _>(v);
assert_eq!(result, vec![1, 3, 5]);
}
#[test]
fn par_separate_basic() {
let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3), Err("b")];
let (errs, oks): (Vec<&str>, Vec<i32>) = par_separate::<VecBrand, _, _>(v);
assert_eq!(errs, vec!["a", "b"]);
assert_eq!(oks, vec![1, 3]);
}
#[test]
fn par_map_with_index_basic() {
let v = vec![10, 20, 30];
let result: Vec<i32> = par_map_with_index::<VecBrand, _, _>(|i, x: i32| x + i as i32, v);
assert_eq!(result, vec![10, 21, 32]);
}
#[test]
fn par_fold_map_empty() {
let v: Vec<i32> = vec![];
assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "".to_string());
}
#[test]
fn par_fold_map_multiple() {
let v = vec![1, 2, 3];
assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "123".to_string());
}
#[test]
fn par_fold_map_with_index_basic() {
let v = vec![10, 20, 30];
let result: String =
par_fold_map_with_index::<VecBrand, _, _>(|i, x: i32| format!("{i}:{x}"), v);
assert_eq!(result, "0:101:202:30");
}
#[quickcheck]
fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
explicit::filter_map::<VecBrand, _, _, _, _>(identity, x.clone())
== explicit::compact::<VecBrand, _, _, _>(x)
}
#[quickcheck]
fn filterable_filter_map_just(x: Vec<i32>) -> bool {
explicit::filter_map::<VecBrand, _, _, _, _>(Some, x.clone()) == x
}
#[quickcheck]
fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
let l = |i: i32| if i > 5 { Some(i) } else { None };
let composed = |i| explicit::bind::<OptionBrand, _, _, _, _>(r(i), l);
explicit::filter_map::<VecBrand, _, _, _, _>(composed, x.clone())
== explicit::filter_map::<VecBrand, _, _, _, _>(
l,
explicit::filter_map::<VecBrand, _, _, _, _>(r, x),
)
}
#[quickcheck]
fn filterable_filter_consistency(x: Vec<i32>) -> bool {
let p = |i: i32| i % 2 == 0;
let maybe_bool = |i| if p(i) { Some(i) } else { None };
explicit::filter::<VecBrand, _, _, _>(p, x.clone())
== explicit::filter_map::<VecBrand, _, _, _, _>(maybe_bool, x)
}
#[quickcheck]
fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
explicit::partition_map::<VecBrand, _, _, _, _, _>(identity, x.clone())
== explicit::separate::<VecBrand, _, _, _, _>(x)
}
#[quickcheck]
fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
let (_, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(Ok::<_, i32>, x.clone());
oks == x
}
#[quickcheck]
fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
let (errs, _) =
explicit::partition_map::<VecBrand, _, _, _, _, _>(Err::<i32, _>, x.clone());
errs == x
}
#[quickcheck]
fn filterable_partition_consistency(x: Vec<i32>) -> bool {
let p = |i: i32| i % 2 == 0;
let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
let (not_satisfied, satisfied) = explicit::partition::<VecBrand, _, _, _>(p, x.clone());
let (errs, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(either_bool, x);
satisfied == oks && not_satisfied == errs
}
#[quickcheck]
fn witherable_identity(x: Vec<i32>) -> bool {
explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
|i| Some(Some(i)),
x.clone(),
) == Some(x)
}
#[quickcheck]
fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
let lhs = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(p, x.clone());
let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
explicit::separate::<VecBrand, _, _, _, _>,
explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
);
lhs == rhs
}
#[quickcheck]
fn witherable_wither_consistency(x: Vec<i32>) -> bool {
let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
let lhs = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
explicit::compact::<VecBrand, _, _, _>,
explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
);
lhs == rhs
}
#[quickcheck]
fn alt_associativity(
x: Vec<i32>,
y: Vec<i32>,
z: Vec<i32>,
) -> bool {
explicit::alt::<VecBrand, _, _, _>(
explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
z.clone(),
) == explicit::alt::<VecBrand, _, _, _>(x, explicit::alt::<VecBrand, _, _, _>(y, z))
}
#[quickcheck]
fn alt_distributivity(
x: Vec<i32>,
y: Vec<i32>,
) -> bool {
let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
explicit::map::<VecBrand, _, _, _, _>(
f,
explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
) == explicit::alt::<VecBrand, _, _, _>(
explicit::map::<VecBrand, _, _, _, _>(f, x),
explicit::map::<VecBrand, _, _, _, _>(f, y),
)
}
#[quickcheck]
fn plus_left_identity(x: Vec<i32>) -> bool {
explicit::alt::<VecBrand, _, _, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
}
#[quickcheck]
fn plus_right_identity(x: Vec<i32>) -> bool {
explicit::alt::<VecBrand, _, _, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
}
#[test]
fn plus_annihilation() {
let f = |i: i32| i.wrapping_mul(2);
assert_eq!(
explicit::map::<VecBrand, _, _, _, _>(f, plus_empty::<VecBrand, i32>()),
plus_empty::<VecBrand, i32>(),
);
}
#[quickcheck]
fn compactable_functor_identity(fa: Vec<i32>) -> bool {
explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
Some,
fa.clone(),
)) == fa
}
#[test]
fn compactable_plus_annihilation_empty() {
assert_eq!(
explicit::compact::<VecBrand, _, _, _>(plus_empty::<VecBrand, Option<i32>>()),
plus_empty::<VecBrand, i32>(),
);
}
#[quickcheck]
fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
|_: i32| None::<i32>,
xs,
)) == plus_empty::<VecBrand, i32>()
}
#[test]
fn compact_empty() {
assert_eq!(
explicit::compact::<VecBrand, i32, _, _>(vec![] as Vec<Option<i32>>),
vec![] as Vec<i32>
);
}
#[test]
fn compact_with_none() {
assert_eq!(
explicit::compact::<VecBrand, i32, _, _>(vec![Some(1), None, Some(2)]),
vec![1, 2]
);
}
#[test]
fn separate_empty() {
let (errs, oks) =
explicit::separate::<VecBrand, i32, i32, _, _>(vec![] as Vec<Result<i32, i32>>);
assert_eq!(oks, vec![] as Vec<i32>);
assert_eq!(errs, vec![] as Vec<i32>);
}
#[test]
fn separate_mixed() {
let (errs, oks) =
explicit::separate::<VecBrand, i32, i32, _, _>(vec![Ok(1), Err(2), Ok(3)]);
assert_eq!(oks, vec![1, 3]);
assert_eq!(errs, vec![2]);
}
#[test]
fn partition_map_empty() {
let (errs, oks) =
explicit::partition_map::<VecBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
assert_eq!(oks, vec![] as Vec<i32>);
assert_eq!(errs, vec![] as Vec<i32>);
}
#[test]
fn partition_empty() {
let (not_satisfied, satisfied) =
explicit::partition::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]);
assert_eq!(satisfied, vec![] as Vec<i32>);
assert_eq!(not_satisfied, vec![] as Vec<i32>);
}
#[test]
fn filter_map_empty() {
assert_eq!(
explicit::filter_map::<VecBrand, i32, _, _, _>(|x: i32| Some(x), vec![]),
vec![] as Vec<i32>
);
}
#[test]
fn filter_empty() {
assert_eq!(
explicit::filter::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]),
vec![] as Vec<i32>
);
}
#[test]
fn wilt_empty() {
let res = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
|x: i32| Some(Ok::<i32, i32>(x)),
vec![],
);
assert_eq!(res, Some((vec![], vec![])));
}
#[test]
fn wither_empty() {
let res = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
|x: i32| Some(Some(x)),
vec![],
);
assert_eq!(res, Some(vec![]));
}
#[test]
fn test_large_vector_par_fold_map() {
use crate::types::Additive;
let xs: Vec<i32> = (0 .. 100000).collect();
let res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
assert_eq!(res, Additive(4999950000));
}
#[quickcheck]
fn prop_par_map_equals_map(xs: Vec<i32>) -> bool {
let f = |x: i32| x.wrapping_add(1);
let seq_res = explicit::map::<VecBrand, _, _, _, _>(f, xs.clone());
let par_res = par_map::<VecBrand, _, _>(f, xs);
seq_res == par_res
}
#[quickcheck]
fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
use crate::types::Additive;
let f = |x: i32| Additive(x as i64);
let seq_res =
crate::functions::explicit::fold_map::<crate::brands::RcFnBrand, VecBrand, _, _, _, _>(
f,
xs.clone(),
);
let par_res = par_fold_map::<VecBrand, _, _>(f, xs);
seq_res == par_res
}
#[quickcheck]
fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
use crate::types::Additive;
if !xs.is_empty() {
return true;
}
let par_res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
par_res == empty::<Additive<i64>>()
}
#[quickcheck]
fn monad_rec_identity(x: i32) -> bool {
use {
crate::classes::monad_rec::tail_rec_m,
core::ops::ControlFlow,
};
tail_rec_m::<VecBrand, _, _>(|a| vec![ControlFlow::Break(a)], x) == vec![x]
}
#[test]
fn monad_rec_linear() {
use {
crate::classes::monad_rec::tail_rec_m,
core::ops::ControlFlow,
};
let result = tail_rec_m::<VecBrand, _, _>(
|n| {
if n < 5 { vec![ControlFlow::Continue(n + 1)] } else { vec![ControlFlow::Break(n)] }
},
0,
);
assert_eq!(result, vec![5]);
}
#[test]
fn monad_rec_branching() {
use {
crate::classes::monad_rec::tail_rec_m,
core::ops::ControlFlow,
};
let result = tail_rec_m::<VecBrand, _, _>(
|n: i32| {
if n < 2 {
vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 100)]
} else {
vec![ControlFlow::Break(n * 100)]
}
},
0,
);
assert_eq!(result, vec![0, 100, 200]);
}
#[test]
fn monad_rec_empty() {
use {
crate::classes::monad_rec::tail_rec_m,
core::ops::ControlFlow,
};
let result: Vec<i32> =
tail_rec_m::<VecBrand, _, _>(|_n| Vec::<ControlFlow<i32, i32>>::new(), 0);
assert_eq!(result, Vec::<i32>::new());
}
#[test]
fn extend_sum_of_suffixes() {
use crate::classes::extend::extend;
let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
assert_eq!(result, vec![6, 5, 3]);
}
#[quickcheck]
fn extend_associativity(w: Vec<i32>) -> bool {
use crate::classes::extend::extend;
let g = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_mul(2).wrapping_add(*b));
let f = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_add(b.wrapping_add(1)));
let lhs = extend::<VecBrand, _, _>(f, extend::<VecBrand, _, _>(g, w.clone()));
let rhs = extend::<VecBrand, _, _>(|w: Vec<i32>| f(extend::<VecBrand, _, _>(g, w)), w);
lhs == rhs
}
#[test]
fn extend_duplicate_suffixes() {
use crate::classes::extend::duplicate;
let result = duplicate::<VecBrand, _>(vec![1, 2, 3]);
assert_eq!(result, vec![vec![1, 2, 3], vec![2, 3], vec![3]]);
}
#[test]
fn extend_empty() {
use crate::classes::extend::extend;
let result =
extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), Vec::<i32>::new());
assert_eq!(result, Vec::<i32>::new());
}
#[test]
fn extend_singleton() {
use crate::classes::extend::extend;
let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![42]);
assert_eq!(result, vec![42]);
}
#[quickcheck]
fn ref_functor_identity(v: Vec<i32>) -> bool {
use crate::classes::ref_functor::RefFunctor;
VecBrand::ref_map(|x: &i32| *x, &v) == v
}
#[quickcheck]
fn ref_functor_composition(v: Vec<i32>) -> bool {
use crate::classes::ref_functor::RefFunctor;
let f = |x: &i32| x.wrapping_add(1);
let g = |x: &i32| x.wrapping_mul(2);
VecBrand::ref_map(|x: &i32| g(&f(x)), &v) == VecBrand::ref_map(g, &VecBrand::ref_map(f, &v))
}
#[quickcheck]
fn ref_foldable_additive(v: Vec<i32>) -> bool {
use crate::{
brands::RcFnBrand,
classes::ref_foldable::RefFoldable,
types::Additive,
};
let result: Additive<i32> =
VecBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &v);
result.0 == v.iter().copied().fold(0i32, |a, b| a.wrapping_add(b))
}
#[quickcheck]
fn ref_semimonad_left_identity(x: i32) -> bool {
use crate::classes::ref_semimonad::RefSemimonad;
VecBrand::ref_bind(&vec![x], |a: &i32| vec![*a]) == vec![x]
}
#[quickcheck]
fn ref_semimonad_associativity(v: Vec<i32>) -> bool {
use crate::classes::ref_semimonad::RefSemimonad;
let f = |a: &i32| vec![a.wrapping_add(1), a.wrapping_mul(2)];
let g = |b: &i32| vec![b.wrapping_add(10)];
let lhs = VecBrand::ref_bind(&VecBrand::ref_bind(&v, f), g);
let rhs = VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_bind(&f(a), g));
lhs == rhs
}
#[quickcheck]
fn par_ref_functor_equivalence(v: Vec<i32>) -> bool {
use crate::classes::{
par_ref_functor::ParRefFunctor,
ref_functor::RefFunctor,
};
let f = |x: &i32| x.wrapping_mul(3).wrapping_add(7);
VecBrand::par_ref_map(f, &v) == VecBrand::ref_map(f, &v)
}
#[quickcheck]
fn ref_semimonad_right_identity(v: Vec<i32>) -> bool {
use crate::classes::{
ref_pointed::RefPointed,
ref_semimonad::RefSemimonad,
};
VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_pure(a)) == v
}
#[quickcheck]
fn ref_lift_identity(v: Vec<i32>) -> bool {
use crate::classes::ref_lift::RefLift;
VecBrand::ref_lift2(|_: &(), b: &i32| *b, &vec![()], &v) == v
}
#[quickcheck]
fn ref_traversable_identity(v: Vec<i32>) -> bool {
use crate::{
classes::ref_traversable::RefTraversable,
types::Identity,
};
let result: Identity<Vec<i32>> =
VecBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(|a: &i32| Identity(*a), &v);
result == Identity(v)
}
#[quickcheck]
fn ref_traversable_consistent_with_traverse(v: Vec<i32>) -> bool {
use crate::classes::{
ref_traversable::RefTraversable,
traversable::Traversable,
};
let ref_result: Option<Vec<String>> = VecBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
|a: &i32| Some(a.to_string()),
&v,
);
let val_result: Option<Vec<String>> =
VecBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), v);
ref_result == val_result
}
#[quickcheck]
fn ref_compactable_identity(v: Vec<i32>) -> bool {
let mapped: Vec<Option<i32>> = v.iter().map(|a| Some(*a)).collect();
explicit::compact::<VecBrand, _, _, _>(&mapped) == v
}
#[quickcheck]
fn ref_alt_associativity(
x: Vec<i32>,
y: Vec<i32>,
z: Vec<i32>,
) -> bool {
explicit::alt::<VecBrand, _, _, _>(&explicit::alt::<VecBrand, _, _, _>(&x, &y), &z)
== explicit::alt::<VecBrand, _, _, _>(&x, &explicit::alt::<VecBrand, _, _, _>(&y, &z))
}
#[quickcheck]
fn ref_alt_distributivity(
x: Vec<i32>,
y: Vec<i32>,
) -> bool {
let f = |a: &i32| a.wrapping_mul(2);
explicit::map::<VecBrand, _, _, _, _>(f, &explicit::alt::<VecBrand, _, _, _>(&x, &y))
== explicit::alt::<VecBrand, _, _, _>(
&explicit::map::<VecBrand, _, _, _, _>(f, &x),
&explicit::map::<VecBrand, _, _, _, _>(f, &y),
)
}
}