pub trait RefFunctor: Kind_cdc7cd43dac7585f {
// Required method
fn ref_map<'a, A: 'a, B: 'a>(
func: impl Fn(&A) -> B + 'a,
fa: &<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>;
}Expand description
A type class for types that can be mapped over, returning references.
This is a variant of Functor for types where map receives/returns references.
This is required for types like Lazy where get() returns &A, not A.
RefFunctor is intentionally independent from
SendRefFunctor. Although one might
expect SendRefFunctor to be a subtrait of RefFunctor, this is not the case because
ArcLazy::new requires Send on the closure, which a generic RefFunctor cannot
guarantee. As a result, ArcLazy implements only SendRefFunctor, not RefFunctor,
and RcLazy implements only RefFunctor, not SendRefFunctor.
§Laws
RefFunctor instances must satisfy the following laws:
Identity: ref_map(|x| x.clone(), fa) is equivalent to fa, given A: Clone.
The Clone requirement arises because the mapping function receives &A but must
produce a value of type A to satisfy the identity law.
Composition: ref_map(|x| g(&f(x)), fa) is equivalent to
ref_map(g, ref_map(f, fa)).
§Examples
RefFunctor laws for Lazy:
use fp_library::{
brands::*,
functions::explicit::*,
types::*,
};
// Identity: ref_map(|x| x.clone(), fa) evaluates to the same value as fa.
let fa = RcLazy::pure(5);
let mapped = map::<LazyBrand<RcLazyConfig>, _, _, _, _>(|x: &i32| *x, &fa);
assert_eq!(*mapped.evaluate(), *fa.evaluate());
// Composition: ref_map(|x| g(&f(x)), fa) = ref_map(g, ref_map(f, fa))
let f = |x: &i32| *x * 2;
let g = |x: &i32| x + 1;
let fa = RcLazy::pure(5);
let composed = map::<LazyBrand<RcLazyConfig>, _, _, _, _>(|x: &i32| g(&f(x)), &fa);
let sequential = map::<LazyBrand<RcLazyConfig>, _, _, _, _>(
g,
&map::<LazyBrand<RcLazyConfig>, _, _, _, _>(f, &fa),
);
assert_eq!(*composed.evaluate(), *sequential.evaluate());§Cache chain behavior
Chaining ref_map calls on memoized types like Lazy creates
a linked list of Rc/Arc-referenced cells. Each mapped value retains a reference to
its predecessor, so the entire chain of predecessor cells stays alive as long as any
downstream mapped value is reachable. Be aware that long chains can accumulate memory
that is only freed when the final value in the chain is dropped.
§Why Fn (not FnOnce)?
The func parameter uses Fn rather than FnOnce because multi-element
containers like Vec call the closure once per element. FnOnce would
restrict RefFunctor to single-element containers. Closures that move
out of their captures (FnOnce but not Fn) cannot be used with
ref_map; these are rare and can be restructured by extracting the
move into a surrounding scope.
Required Methods§
Sourcefn ref_map<'a, A: 'a, B: 'a>(
func: impl Fn(&A) -> B + 'a,
fa: &<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>
fn ref_map<'a, A: 'a, B: 'a>( func: impl Fn(&A) -> B + 'a, fa: &<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>
Maps a function over the values in the functor context, where the function takes a reference.
§Type Signature
forall A B. (&A -> B, &Self A) -> Self B
§Type Parameters
'a: The lifetime of the values.A: The type of the value(s) inside the functor.B: The type of the result(s) of applying the function.
§Parameters
func: The function to apply to the value(s) inside the functor.fa: The functor instance containing the value(s).
§Returns
A new functor instance containing the result(s) of applying the function.
§Examples
use fp_library::{
brands::*,
classes::*,
types::*,
};
let memo = Lazy::<_, RcLazyConfig>::new(|| 10);
let mapped = LazyBrand::<RcLazyConfig>::ref_map(|x: &i32| *x * 2, &memo);
assert_eq!(*mapped.evaluate(), 20);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.
Implementors§
impl RefFunctor for CatListBrand
impl RefFunctor for IdentityBrand
impl RefFunctor for LazyBrand<RcLazyConfig>
impl RefFunctor for OptionBrand
impl RefFunctor for Tuple1Brand
impl RefFunctor for VecBrand
impl<Brand: Bifunctor + RefBifunctor, A: Clone + 'static> RefFunctor for BifunctorFirstAppliedBrand<Brand, A>
RefFunctor instance for BifunctorFirstAppliedBrand.
Maps over the first type parameter of a bifunctor by reference, delegating to
RefBifunctor::ref_bimap with Clone::clone for the second argument.
Requires Clone on the fixed second type parameter because the value must be
cloned out of the borrowed container.
§Type Parameters
Brand: The bifunctor brand.A: The fixed second type parameter.
impl<Brand: Bifunctor + RefBifunctor, B: Clone + 'static> RefFunctor for BifunctorSecondAppliedBrand<Brand, B>
RefFunctor instance for BifunctorSecondAppliedBrand.
Maps over the second type parameter of a bifunctor by reference, delegating to
RefBifunctor::ref_bimap with Clone::clone for the first argument.
Requires Clone on the fixed first type parameter because the value must be
cloned out of the borrowed container.
§Type Parameters
Brand: The bifunctor brand.B: The fixed first type parameter.
impl<E: 'static + Clone> RefFunctor for TryLazyBrand<E, RcLazyConfig>
§Type Parameters
E: The type of the error.
impl<E: Clone + 'static> RefFunctor for ResultErrAppliedBrand<E>
§Type Parameters
E: The error type.
impl<First: Clone + 'static> RefFunctor for PairFirstAppliedBrand<First>
§Type Parameters
First: The type of the first value in the pair.
impl<First: Clone + 'static> RefFunctor for Tuple2FirstAppliedBrand<First>
§Type Parameters
First: The type of the first value in the tuple.
impl<Second: Clone + 'static> RefFunctor for PairSecondAppliedBrand<Second>
§Type Parameters
Second: The type of the second value in the pair.
impl<Second: Clone + 'static> RefFunctor for Tuple2SecondAppliedBrand<Second>
§Type Parameters
Second: The type of the second value in the tuple.
impl<T: Clone + 'static> RefFunctor for ResultOkAppliedBrand<T>
§Type Parameters
T: The success type.