#[fp_macros::document_module]
mod inner {
use {
crate::{
classes::{
send_clone_fn::SendLiftFn,
*,
},
functions::identity,
},
fp_macros::*,
std::fmt::{
self,
Debug,
Formatter,
},
};
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the thread-safe cloneable function wrapper.",
"The input and output type of the function."
)]
pub struct SendEndofunction<'a, FnBrand: SendLiftFn, A: 'a>(
pub <FnBrand as SendCloneFn>::Of<'a, A, A>,
);
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function (e.g., `ArcFnBrand`).",
"The input and output type of the function."
)]
impl<'a, FnBrand: SendLiftFn, A: 'a> SendEndofunction<'a, FnBrand, A> {
#[document_signature]
#[document_parameters("The function to wrap.")]
#[document_returns("A new `SendEndofunction`.")]
#[document_examples]
pub fn new(f: <FnBrand as SendCloneFn>::Of<'a, A, A>) -> Self {
Self(f)
}
}
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function (e.g., `ArcFnBrand`).",
"The input and output type of the function."
)]
#[document_parameters("The function to clone.")]
impl<'a, FnBrand: SendLiftFn, A: 'a> Clone for SendEndofunction<'a, FnBrand, A> {
#[document_signature]
#[document_returns("The cloned endofunction.")]
#[document_examples]
fn clone(&self) -> Self {
Self::new(self.0.clone())
}
}
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function (e.g., `ArcFnBrand`).",
"The input and output type of the function."
)]
#[document_parameters("The function to format.")]
impl<'a, FnBrand: SendLiftFn, A: 'a> Debug for SendEndofunction<'a, FnBrand, A>
where
<FnBrand as SendCloneFn>::Of<'a, A, A>: Debug,
{
#[document_signature]
#[document_parameters("The formatter to use.")]
#[document_returns("The result of the formatting operation.")]
#[document_examples]
fn fmt(
&self,
fmt: &mut Formatter<'_>,
) -> fmt::Result {
fmt.debug_tuple("SendEndofunction").field(&self.0).finish()
}
}
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function (e.g., `ArcFnBrand`).",
"The input and output type of the function."
)]
impl<'a, FnBrand: 'a + SendLiftFn, A: 'a + Send + Sync> Semigroup
for SendEndofunction<'a, FnBrand, A>
{
#[document_signature]
#[document_parameters(
"The second function to apply (the outer function).",
"The first function to apply (the inner function)."
)]
#[document_returns("The composed function `a . b`.")]
#[document_examples]
fn append(
a: Self,
b: Self,
) -> Self {
let f = a.0;
let g = b.0;
Self::new(<FnBrand as SendLiftFn>::new(move |x| f(g(x))))
}
}
#[document_type_parameters(
"The lifetime of the function and its captured data.",
"The brand of the function (e.g., `ArcFnBrand`).",
"The input and output type of the function."
)]
impl<'a, FnBrand: 'a + SendLiftFn, A: 'a + Send + Sync> Monoid
for SendEndofunction<'a, FnBrand, A>
{
#[document_signature]
#[document_returns("The identity endofunction.")]
#[document_examples]
fn empty() -> Self {
Self::new(<FnBrand as SendLiftFn>::new(identity))
}
}
}
pub use inner::*;
#[cfg(test)]
mod tests {
use {
super::*,
crate::{
brands::ArcFnBrand,
classes::send_clone_fn::SendLiftFn,
functions::*,
},
quickcheck_macros::quickcheck,
};
#[quickcheck]
fn semigroup_associativity(val: i32) -> bool {
let f =
SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
x.wrapping_add(1)
}));
let g =
SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
x.wrapping_mul(2)
}));
let h =
SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
x.wrapping_sub(3)
}));
let lhs = append(f.clone(), append(g.clone(), h.clone()));
let rhs = append(append(f, g), h);
lhs.0(val) == rhs.0(val)
}
#[quickcheck]
fn monoid_left_identity(val: i32) -> bool {
let f =
SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
x.wrapping_add(1)
}));
let id = empty::<SendEndofunction<ArcFnBrand, i32>>();
let res = append(id, f.clone());
res.0(val) == f.0(val)
}
#[quickcheck]
fn monoid_right_identity(val: i32) -> bool {
let f =
SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
x.wrapping_add(1)
}));
let id = empty::<SendEndofunction<ArcFnBrand, i32>>();
let res = append(f.clone(), id);
res.0(val) == f.0(val)
}
}