pub trait FuncMap<A, B, P = TypeParam<0>>: Sizedwhere
P: FuncMarker<P>,{
type Output;
// Required method
fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B;
// Provided method
fn func_map_over<Q, F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,
Q: FuncMarker<P> { ... }
}Expand description
Functorial mapping of a generic type over any of its type parameters
§Deriving FuncMap
In most cases, implementations of this trait can and should be derived automatically:
#[derive(FuncMap)]
struct Foo<T> {
// ...
}See the crate-level documentation for details.
§Manually Implementing FuncMap
If you need to implement FuncMap manually, make sure to uphold the
following contract:
Let Foo be a type that is generic over the type or const parameters
T0, ..., Tn.
If Foo implements FuncMap<A, B, TypeParam<N>>, then
Nmust be in the range0..=n.- The parameter of
Fooat indexN(not counting lifetime parameters) must beA. In particular, it must be a type parameter, not a const generic. Foo::Outputmust beFoowith the parameter at indexNreplaced withB.
Furthermore:
func_map_overmust behave in exactly the same way asfunc_map. This is the default behavior and must not be changed.- When implementing
FuncMapfor different marker typesTypeParam<N>andTypeParam<M>, the result of mapping over both type parameters in sequence must not depend on the order of the two mappings, i.e.foo.func_map_over::<TypeParam<N>, _>(f) .func_map_over::<TypeParam<M>, _>(g) // must be equivalent to foo.func_map_over::<TypeParam<M>, _>(g) .func_map_over::<TypeParam<N>, _>(f)
Required Associated Types§
Required Methods§
Provided Methods§
Sourcefn func_map_over<Q, F>(self, f: F) -> Self::Outputwhere
F: FnMut(A) -> B,
Q: FuncMarker<P>,
fn func_map_over<Q, F>(self, f: F) -> Self::Outputwhere
F: FnMut(A) -> B,
Q: FuncMarker<P>,
Applies the closure f to self in a functorial way, allowing explicit
specification of the marker type P
This is a convenience method that has the exact same functionality as
func_map but can be used to specify the marker type
P in a convenient way in cases where it is ambiguous.
So if you have
#[derive(FuncMap, Debug, PartialEq)]
struct Foo<S, T> {
s: S,
t: T,
}
let foo = Foo {
s: 42,
t: 42,
};then instead of writing
let bar = FuncMap::<_, _, TypeParam<1>>::func_map(foo, |v| v + 1);
assert_eq!(bar, Foo { s: 42, t: 43 });you can more conveniently write
let bar = foo.func_map_over::<TypeParam<1>, _>(|v| v + 1);
assert_eq!(bar, Foo { s: 42, t: 43 });This lets you chain method calls more easily as in
foo.func_map_over::<TypeParam<0>, _>(|v| v + 1)
.func_map_over::<TypeParam<1>, _>(|v| v + 1)Note that you still need to specify the inferred type _ for the
closure type F.
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.