#[fp_macros::document_module]
mod inner {
use {
crate::{
Apply,
brands::optics::*,
classes::{
ToDynCloneFn,
monoid::Monoid,
optics::*,
},
kinds::*,
types::optics::Forget,
},
fp_macros::*,
std::marker::PhantomData,
};
pub use crate::classes::optics::fold::FoldFunc;
#[document_type_parameters("The type of the inner function.")]
pub struct IterableFoldFn<F>(pub F);
#[document_type_parameters("The type of the inner function.")]
#[document_parameters("The fold instance.")]
impl<F: Clone> Clone for IterableFoldFn<F> {
#[document_signature]
#[document_returns("A new `Fold` instance that is a copy of the original.")]
#[document_examples]
fn clone(&self) -> Self {
IterableFoldFn(self.0.clone())
}
}
#[document_type_parameters(
"The lifetime of the function.",
"The source type of the structure.",
"The type of the focuses.",
"The iterable type returned by the function.",
"The type of the inner function."
)]
#[document_parameters("The fold instance.")]
impl<'a, S, A, I, F> FoldFunc<'a, S, A> for IterableFoldFn<F>
where
F: Fn(S) -> I,
I: IntoIterator<Item = A>,
{
#[document_signature]
#[document_type_parameters("The monoid type to fold into.")]
#[document_parameters("The mapping function.", "The structure to fold.")]
#[document_returns("The combined monoid value.")]
#[document_examples]
fn apply<R: Monoid>(
&self,
f: impl Fn(A) -> R + 'a,
s: S,
) -> R {
(self.0)(s).into_iter().fold(R::empty(), |r, a| R::append(r, f(a)))
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The source type of the structure.",
"The target type of the structure.",
"The source type of the focus.",
"The target type of the focus.",
"The type of the fold function."
)]
pub struct Fold<'a, PointerBrand, S, T, A, B, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A>,
S: 'a,
T: 'a,
A: 'a,
B: 'a, {
pub fold_fn: F,
pub(crate) _phantom: PhantomData<(&'a (S, T, A, B), PointerBrand)>,
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The source type of the structure.",
"The target type of the structure.",
"The source type of the focus.",
"The target type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, T, A, B, F> Clone for Fold<'a, PointerBrand, S, T, A, B, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A> + Clone,
S: 'a,
T: 'a,
A: 'a,
B: 'a,
{
#[document_signature]
#[document_returns("A new `Fold` instance that is a copy of the original.")]
#[document_examples]
fn clone(&self) -> Self {
Fold {
fold_fn: self.fold_fn.clone(),
_phantom: PhantomData,
}
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The source type of the structure.",
"The target type of the structure.",
"The source type of the focus.",
"The target type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, T, A, B, F> Fold<'a, PointerBrand, S, T, A, B, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A>,
S: 'a,
T: 'a,
A: 'a,
B: 'a,
{
#[document_signature]
#[document_parameters("The fold function.")]
#[document_returns("A new instance of the type.")]
#[document_examples]
pub fn new(fold_fn: F) -> Self {
Fold {
fold_fn,
_phantom: PhantomData,
}
}
#[document_signature]
#[document_parameters("The structure to fold.")]
#[document_returns("A `Vec` containing all the focuses.")]
#[document_examples]
pub fn to_vec(
&self,
s: S,
) -> Vec<A>
where
A: Clone, {
self.fold_fn.apply::<Vec<A>>(|a| vec![a], s)
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The source type of the structure.",
"The target type of the structure.",
"The source type of the focus.",
"The target type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, T, A, B, F> FoldOptic<'a, S, A> for Fold<'a, PointerBrand, S, T, A, B, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A> + Clone + 'a,
S: 'a,
T: 'a,
A: 'a,
B: 'a,
{
#[document_signature]
#[document_type_parameters(
"The monoid type.",
"The reference-counted pointer type for the Forget brand."
)]
#[document_parameters("The profunctor value to transform.")]
#[document_returns("The transformed profunctor value.")]
#[document_examples]
fn evaluate<R: 'a + Monoid + 'static, Q: ToDynCloneFn + 'static>(
&self,
pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, A, A>),
) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, S, S>)
{
let fold_fn = self.fold_fn.clone();
Forget::<Q, R, S, S>::new(move |s: S| {
let pab_fn = pab.0.clone();
fold_fn.apply::<R>(move |a| (pab_fn)(a), s)
})
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The type of the structure.",
"The type of the focus.",
"The type of the fold function."
)]
pub struct FoldPrime<'a, PointerBrand, S, A, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A>,
S: 'a,
A: 'a, {
pub fold_fn: F,
pub(crate) _phantom: PhantomData<(&'a (S, A), PointerBrand)>,
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The type of the structure.",
"The type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, A, F> Clone for FoldPrime<'a, PointerBrand, S, A, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A> + Clone,
S: 'a,
A: 'a,
{
#[document_signature]
#[document_returns("A new `FoldPrime` instance that is a copy of the original.")]
#[document_examples]
fn clone(&self) -> Self {
FoldPrime {
fold_fn: self.fold_fn.clone(),
_phantom: PhantomData,
}
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The type of the structure.",
"The type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, A, F> FoldPrime<'a, PointerBrand, S, A, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A>,
S: 'a,
A: 'a,
{
#[document_signature]
#[document_parameters("The fold function.")]
#[document_returns("A new instance of the type.")]
#[document_examples]
pub fn new(fold_fn: F) -> Self {
FoldPrime {
fold_fn,
_phantom: PhantomData,
}
}
#[document_signature]
#[document_parameters("The structure to fold.")]
#[document_returns("A `Vec` containing all the focuses.")]
#[document_examples]
pub fn to_vec(
&self,
s: S,
) -> Vec<A>
where
A: Clone, {
self.fold_fn.apply::<Vec<A>>(|a| vec![a], s)
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The reference-counted pointer type.",
"The type of the structure.",
"The type of the focus.",
"The type of the fold function."
)]
#[document_parameters("The fold instance.")]
impl<'a, PointerBrand, S, A, F> FoldOptic<'a, S, A> for FoldPrime<'a, PointerBrand, S, A, F>
where
PointerBrand: ToDynCloneFn,
F: FoldFunc<'a, S, A> + Clone + 'a,
S: 'a,
A: 'a,
{
#[document_signature]
#[document_type_parameters(
"The monoid type.",
"The reference-counted pointer type for the Forget brand."
)]
#[document_parameters("The profunctor value to transform.")]
#[document_returns("The transformed profunctor value.")]
#[document_examples]
fn evaluate<R: 'a + Monoid + 'static, Q: ToDynCloneFn + 'static>(
&self,
pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, A, A>),
) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, S, S>)
{
let fold_fn = self.fold_fn.clone();
Forget::<Q, R, S, S>::new(move |s: S| {
let pab_fn = pab.0.clone();
fold_fn.apply::<R>(move |a| (pab_fn)(a), s)
})
}
}
}
pub use inner::*;