gpt4 book ai didi

rust - Rust中的部分应用程序宏可以工作,但是

转载 作者:行者123 更新时间:2023-12-03 11:37:19 24 4
gpt4 key购买 nike

因此,我正在编写(尝试)一些可变的宏,以尝试在 rust 中实现组合和 curry 。 pipe很简单。
可变参数部分应用了吗?没那么多。对任何可以为不使用那些令人讨厌的看似可忽略的类型args的部分应用程序宏提出解决方案的人(可能是可变参数?没有反射,我认为这是不可能的):

    //ltr compose for closures
macro_rules! pipe {
($init:tt |> $($fn:ident),+) => {{
let mut r = $init;
$( r = $fn(r); )*
r
}}
}

//partially apply a closure w/ up to 4 args
macro_rules! apply {
($fn:ident<$t1:ty,$t2:ty>($arg1:expr)) => {
|x:$t2| $fn($arg1 as $t1, x)
};
($fn:ident<$t1:ty,$t2:ty,$t3:ty>($arg1:expr)) => {
|x:$t2, y:$t3| $fn($arg1 as $t1,x, y)
};
($fn:ident<$t1:ty,$t2:ty,$t3:ty>($arg1:expr, $arg2:expr)) => {
|x:$t3| $fn($arg1 as $t1,$arg2 as $t2,x)
};
($fn:ident<$t1:ty,$t2:ty,$t3:ty,$t4:ty>($arg1:expr)) => {
|x: $t2, y:$t3, z:$t4| $fn($arg1 as $t1, x, y, z)
};
($fn:ident<$t1:ty,$t2:ty,$t3:ty,$t4:ty>($arg1:expr, $arg2:expr)) => {
|x:$t3, y:$t4| $fn($arg1 as $t1,$arg2 as $t2, x, y)
};
($fn:ident<$t1:ty,$t2:ty,$t3:ty,$t4:ty>($arg1:expr, $arg2:expr, $arg3:expr)) => {
|x:$t4| $fn($arg1 as $t1,$arg2 as $t2,arg3 as $t3,x)
};
}

fn main() {


let add = |x:i32, y:i32| x + y;
let sq = |x:i32| x * x;
let dbl = |x:i32| x * 2;
//blargh i hate those typeargs! i need them for the matcher
//to get the original params number and type since rust has no reflection :(
//weirdly if i ignore them with _ it works. But it will luckily fail
//hard if you supply incorrect args.
let plus1 = apply!(add<_,_>(1));

let r = pipe!(3 |> dbl, plus1, sq);

print!("{}", r);
}
编辑:我似乎无法对此执行可变参数的原因是因为这更改了闭包的结构。乍一看似乎不错,我只是将其包装在match语句中,该语句基于总参数以及exprs数量与总参数之间的差。但是如果您尝试在匹配臂中返回不同签名的闭包,则不会编译。好消息是这种方法的开销可能很低。但是,通过部分必要的内联闭包,对于部分应用程序确实不是一个很大的改进:
//simple, works, no type args or even type declarations on params I'm just a crazy person who wants it all!
let add = |x, y| x + y;
let add1 = |x| add(x, 1);
因此,这实际上只是学术上的追求,似乎不切实际

最佳答案

我不确定我是否理解您的问题,但是我认为也许这个库可以为您提供帮助:https://docs.rs/partial_application/0.2.0/partial_application/

#[macro_use]
extern crate partial_application;

//ltr compose for closures
macro_rules! pipe {
($init:tt |> $($fn:ident),+) => {{
let mut r = $init;
$( r = $fn(r); )*
r
}}
}

fn main() {


let add = |x:i32, y:i32| x + y;
let sq = |x:i32| x * x;
let dbl = |x:i32| x * 2;
//blargh i hate those typeargs! i need them for the matcher
//to get the original params number and type since rust has no reflection :(
//weirdly if i ignore them with _ it works. But it will luckily fail
//hard if you supply incorrect args.
let plus1 = partial!(add => 1,_);
let r = pipe!(3 |> dbl, plus1, sq);

print!("{}", r);
}
您可以引用此库来创建自己的宏。

关于rust - Rust中的部分应用程序宏可以工作,但是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62493207/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com