Trait FuncMap

Source
pub trait FuncMap<A, B, P = TypeParam<0>>: Sized
where 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 range 0..=n.
  • The parameter of Foo at index N (not counting lifetime parameters) must be A. In particular, it must be a type parameter, not a const generic.
  • Foo::Output must be Foo with the parameter at index N replaced with B.

Furthermore:

  • func_map_over must behave in exactly the same way as func_map. This is the default behavior and must not be changed.
  • When implementing FuncMap for different marker types TypeParam<N> and TypeParam<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§

Source

type Output

The output type of the functorial mapping

This is Self with the parameter at index N replaced with B, where N is such that P is TypeParam<N>.

In the simplest case of a type with just a single type parameter, if Self is Foo<A>, then this is Foo<B>.

Required Methods§

Source

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Applies the closure f to self in a functorial way

Provided Methods§

Source

fn func_map_over<Q, F>(self, f: F) -> Self::Output
where 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.

Examples found in repository?
examples/multi_param.rs (line 28)
21
22
23
24
25
26
27
28
29
30
    fn into_base(self) -> Measurements<Meter, Kilogram>
    where
        L: Into<Meter>,
        M: Into<Kilogram>,
    {
        // use `func_map_over` to specify the type parameter of `Measurements`
        // over which the mapping is to be performed
        self.func_map_over::<LengthParam, _>(Into::into)
            .func_map_over::<MassParam, _>(Into::into)
    }

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.

Implementations on Foreign Types§

Source§

impl<A, B> FuncMap<A, B> for Bound<A>

Source§

type Output = Bound<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Option<A>

Source§

type Output = Option<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Poll<A>

Source§

type Output = Poll<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Box<A>

Source§

type Output = Box<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for BinaryHeap<A>
where B: Ord,

Source§

type Output = BinaryHeap<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>
where B: Ord,

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for BTreeSet<A>
where B: Ord,

Source§

type Output = BTreeSet<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>
where B: Ord,

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for LinkedList<A>

Source§

type Output = LinkedList<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for VecDeque<A>

Source§

type Output = VecDeque<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Vec<A>

Source§

type Output = Vec<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Cell<A>

Source§

type Output = Cell<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for RefCell<A>

Source§

type Output = RefCell<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for UnsafeCell<A>

Source§

type Output = UnsafeCell<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for PhantomData<A>

Source§

type Output = PhantomData<B>

Source§

fn func_map<F>(self, _: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for Range<A>

Source§

type Output = Range<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for RangeFrom<A>

Source§

type Output = RangeFrom<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for RangeInclusive<A>

Source§

type Output = RangeInclusive<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for RangeTo<A>

Source§

type Output = RangeTo<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for RangeToInclusive<A>

Source§

type Output = RangeToInclusive<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B> FuncMap<A, B> for IntoIter<A>
where B: Eq + Hash,

Source§

type Output = IntoIter<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, S> FuncMap<A, B> for HashSet<A, S>
where B: Eq + Hash,

Source§

type Output = HashSet<B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, U> FuncMap<A, B> for Result<A, U>

Source§

type Output = Result<B, U>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, V> FuncMap<A, B> for BTreeMap<A, V>
where B: Ord,

Source§

type Output = BTreeMap<B, V>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, V> FuncMap<A, B> for IntoIter<A, V>
where B: Ord,

Source§

type Output = IntoIter<B, V>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, V> FuncMap<A, B> for IntoIter<A, V>
where B: Eq + Hash,

Source§

type Output = IntoIter<B, V>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, V, S> FuncMap<A, B> for HashMap<A, V, S>
where B: Eq + Hash,

Source§

type Output = HashMap<B, V>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<A, B, const N: usize> FuncMap<A, B> for [A; N]

Source§

type Output = [B; N]

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<B, T, U> FuncMap<T, U, TypeParam<1>> for ControlFlow<B, T>

Source§

type Output = ControlFlow<B, U>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(T) -> U,

Source§

impl<K, A, B> FuncMap<A, B, TypeParam<1>> for BTreeMap<K, A>
where K: Ord,

Source§

type Output = BTreeMap<K, B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<K, A, B> FuncMap<A, B, TypeParam<1>> for IntoIter<K, A>
where K: Ord,

Source§

type Output = IntoIter<K, B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<K, A, B> FuncMap<A, B, TypeParam<1>> for IntoIter<K, A>
where K: Eq + Hash,

Source§

type Output = IntoIter<K, B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<K, A, B, S> FuncMap<A, B, TypeParam<1>> for HashMap<K, A, S>
where K: Eq + Hash,

Source§

type Output = HashMap<K, B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<T, A, B> FuncMap<A, B, TypeParam<1>> for Result<T, A>

Source§

type Output = Result<T, B>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(A) -> B,

Source§

impl<T, U, C> FuncMap<T, U> for ControlFlow<T, C>

Source§

type Output = ControlFlow<U, C>

Source§

fn func_map<F>(self, f: F) -> Self::Output
where F: FnMut(T) -> U,

Implementors§