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
N
must be in the range0..=n
.- The parameter of
Foo
at indexN
(not counting lifetime parameters) must beA
. In particular, it must be a type parameter, not a const generic. Foo::Output
must beFoo
with the parameter at indexN
replaced withB
.
Furthermore:
func_map_over
must behave in exactly the same way asfunc_map
. This is the default behavior and must not be changed.- When implementing
FuncMap
for 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.