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.