Applied Sign / Apply in Rust

I found this discussion about the distribution of a tuple, but this is from 2014.

The given example:

fn sum(x: i32, y: i32) -> i32 { x + y } fn prepare_args () -> (i32, i32) { (1, 2) } fn main() { sum(prepare_args()); // Doesn't work } 

And the proposed solution is to collapse your own apply function:

 fn apply<A,B,C>(f: |A,B|->C, t: (A,B)) -> C { let (a,b) = t; f(a,b) } fn main() { apply(sum, prepare_args()); } 

Is this the best way now? If so, what is the correct syntax here? I get some errors, including expected type, found | at line 1 col 20 using the above.

Still no tuple binding operator?

+5
source share
3 answers

I do not think there is a splat operator.

The code you found since 2014 is prior to Rust 1.0, so it is deprecated. For the apply function to work in post 1.0 Rust, change it to the following:

 fn sum(x: i32, y: i32) -> i32 { x + y } fn prepare_args() -> (i32, i32) { (1, 2) } fn apply<A, B, C, F>(f: F, t: (A, B)) -> C where F : Fn(A, B) -> C { let (a, b) = t; f(a, b) } fn main() { let x = apply(sum, prepare_args()); println!("{}", x); } 

This code compiles and works correctly on the Rust site .

Instead, you can use f(t.0, t.1) as the apply body or destroy it in the parameter list ( Playground ):

 fn apply<A, B, C, F>(f: F, (a, b): (A, B)) -> C where F : Fn(A, B) -> C { f(a, b) } 
+6
source

The proof of denial is always quite complicated ...

As far as I know, there is actually no character set operator. However, the trait family Fn* ( Fn ) takes one argument as a tuple.

In the night compiler, activating some unstable functions, you can use:

 #![feature(fn_traits)] #![feature(unboxed_closures)] fn sum(x: i32, y: i32) -> i32 { x + y } fn prepare_args () -> (i32, i32) { (1, 2) } fn main() { let func: &Fn(i32, i32) -> i32 = &sum; let result = func.call(prepare_args()); println!("{:?}", result); } 

Not too perfect, but in the absence of variator support, you always need to know the number of elements in your tuple anyway to keep the value low.

+5
source

Here is the version of apply that works for tuples with sizes from 1 to 6 (can be increased) ( Playground ):

 fn main() { let add1 = |x| x + 1; let sum2 = ::std::ops::Add::add; let sum3 = |a, b, c| a + b + c; assert_eq!(apply(add1, (1,)), 2); assert_eq!(apply(sum2, (1, 2)), 3); assert_eq!(apply(sum3, (1, 2, 3)), 6); } #[inline(always)] pub fn apply<Fun, In, Out>(fun: Fun, params: In) -> Out where ApplyImpl: Apply<Fun, In, Out> { ApplyImpl::apply(fun, params) } pub trait Apply<Fun, In, Out> { fn apply(fun: Fun, params: In) -> Out; } pub struct ApplyImpl; macro_rules! impl_apply { () => (); ($A:ident, $($B:ident,)*) => ( impl_apply!{$($B,)*} impl<$A, $($B,)* Fun, Out> Apply<Fun, ($A, $($B),*), Out> for ApplyImpl where Fun: Fn($A, $($B),*) -> Out { #[allow(non_snake_case)] #[inline(always)] fn apply(fun: Fun, params: ($A, $($B),*)) -> Out { // use type parameters as var names... let ($A, $($B),*) = params; fun($A, $($B),*) } } ) } impl_apply!{A, B, C, D, E, F,} 

I am going to create a box for this. If I do, I will put the link here.

+3
source

All Articles