Trait funcmap::FuncMap

source ·
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 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::Outputwhere 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::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.

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)
    }

Implementations on Foreign Types§

source§

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

§

type Output = BinaryHeap<B, Global>

source§

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

source§

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

§

type Output = IntoIter<B, V>

source§

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

source§

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

§

type Output = BTreeMap<B, V, Global>

source§

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

source§

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

§

type Output = Cell<B>

source§

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

source§

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

§

type Output = IntoIter<B, V, Global>

source§

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

source§

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

§

type Output = RangeInclusive<B>

source§

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

source§

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

§

type Output = RangeTo<B>

source§

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

source§

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

§

type Output = IntoIter<B>

source§

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

source§

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

§

type Output = IntoIter<K, B, Global>

source§

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

source§

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

§

type Output = VecDeque<B, Global>

source§

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

source§

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

§

type Output = RefCell<B>

source§

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

source§

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

§

type Output = IntoIter<B, Global>

source§

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

source§

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

§

type Output = HashMap<B, V, RandomState>

source§

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

source§

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

§

type Output = RangeFrom<B>

source§

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

source§

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

§

type Output = IntoIter<B>

source§

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

source§

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

§

type Output = [B; N]

source§

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

source§

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

§

type Output = HashSet<B, RandomState>

source§

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

source§

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

§

type Output = Result<T, B>

source§

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

source§

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

§

type Output = IntoIter<B, Global>

source§

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

source§

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

§

type Output = ControlFlow<B, U>

source§

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

source§

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

§

type Output = Poll<B>

source§

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

source§

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

§

type Output = ControlFlow<U, C>

source§

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

source§

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

§

type Output = Bound<B>

source§

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

source§

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

§

type Output = Vec<B, Global>

source§

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

source§

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

§

type Output = RangeToInclusive<B>

source§

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

source§

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

§

type Output = IntoIter<K, B>

source§

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

source§

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

§

type Output = IntoIter<B, Global>

source§

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

source§

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

§

type Output = IntoIter<B, Global>

source§

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

source§

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

§

type Output = Option<B>

source§

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

source§

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

§

type Output = IntoIter<B, Global>

source§

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

source§

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

§

type Output = BTreeSet<B, Global>

source§

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

source§

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

§

type Output = IntoIter<B>

source§

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

source§

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

§

type Output = Result<B, U>

source§

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

source§

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

§

type Output = UnsafeCell<B>

source§

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

source§

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

§

type Output = LinkedList<B, Global>

source§

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

source§

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

§

type Output = PhantomData<B>

source§

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

source§

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

§

type Output = HashMap<K, B, RandomState>

source§

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

source§

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

§

type Output = Range<B>

source§

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

source§

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

§

type Output = BTreeMap<K, B, Global>

source§

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

source§

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

§

type Output = Box<B, Global>

source§

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

Implementors§