Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Functional programming 如何创建一个宏,该宏接受一个具有多个参数的函数并为该函数提供第一个参数?_Functional Programming_Rust_Currying - Fatal编程技术网

Functional programming 如何创建一个宏,该宏接受一个具有多个参数的函数并为该函数提供第一个参数?

Functional programming 如何创建一个宏,该宏接受一个具有多个参数的函数并为该函数提供第一个参数?,functional-programming,rust,currying,Functional Programming,Rust,Currying,我希望能够创建一个高阶函数(称为g),它接受一个函数(称为f)g应将第一个参数传递到f并返回一个新函数 用例是我想在g中启动一个数据库连接,并将接受数据库连接的函数传递给它 fn f1(a: i32, b: String) -> String { b } fn f2(a: i32, c: i64, d: i16) -> i32 { 1000 } fn g<T>(f: fn(a: i32, arbitrary_arguments_type) ->

我希望能够创建一个高阶函数(称为
g
),它接受一个函数(称为
f
g
应将第一个参数传递到
f
并返回一个新函数

用例是我想在
g
中启动一个数据库连接,并将接受数据库连接的函数传递给它

fn f1(a: i32, b: String) -> String {
    b
}

fn f2(a: i32, c: i64, d: i16) -> i32 {
    1000
}

fn g<T>(f: fn(a: i32, arbitrary_arguments_type) -> T) -> fn(arbitrary_arguments_type) -> T {
    move |arbitrary_arguments| f(1, arbitrary_arguments)
}

fn main() {
    g(f1)("hello".to_string());
    g(f2)(10, 11);
}
fn f1(a:i32,b:String)->String{
B
}
fn f2(a:i32,c:i64,d:i16)->i32{
1000
}
fn g(f:fn(a:i32,任意参数类型)->T)->fn(任意参数类型)->T{
移动|任意参数| f(1,任意参数)
}
fn main(){
g(f1)(“hello.to_string());
g(f2)(10,11);
}
如何创建一个宏,该宏接受一个具有多个参数的函数作为参数,其中第一个参数是特定类型的,并为第一个函数提供该参数

我要问的具体问题是,如何创建一个宏,该宏接受一个具有多个参数的函数作为参数,其中第一个参数是特定类型的,为第一个函数提供该参数

宏(甚至过程宏)在语法树上运行,因此它们不能基于语义(包括类型和函数arity)更改其行为。这意味着您必须为每个可能的参数数使用不同的宏。例如:

macro_rules! curry1 {
    ($func: ident, $($arg: expr),*) => {
        |a| $func($($arg),*, a)
    }
}

macro_rules! curry2 {
    ($func: ident, $($arg: expr),*) => {
        |a, b| $func($($arg),*, a, b)
    }
}

macro_rules! curry3 {
    ($func: ident, $($arg: expr),*) => {
        |a, b, c| $func($($arg),*, a, b, c)
    }
}
使用的方法如下:

fn f(a: i32, b: i32, c: i32) -> i32 {
    a + b + c
}

fn main() {
    // requires 2 extra args
    let f_2 = curry2!(f, 2);
    // requires 1 extra arg
    let f_2_1 = curry1!(f, 2, 1);

    println!("{}", f(2, 1, 3)); // 6
    println!("{}", f_2(1, 3));  // 6
    println!("{}", f_2_1(3));   // 6
}

你的f1和f2是两种不同类型的账户,你能让它们的类型签名相似吗?我相信你的问题已经由的答案回答了。如果你不同意,请用你的问题来解释不同之处。否则,我们可以将这个问题标记为已经回答。@yorodm这个想法是f1和f2将有不同的类型签名,它们之间唯一的相似之处是第一个参数是相同的。