我正在学习如何使用frunk in Rust。
我对如何将foldl method的folder
参数用于具有相同类型特征且具有不同类型参数的元素提出疑问。我在下面写了一个带有foldl方法看似冗余的folder
参数的示例(此示例编译得很好)。
是否有更简单的方法将static_forward
函数传递给foldl
?
#[macro_use]
extern crate frunk;
trait Layer<InDim, OutDim> {
fn forward(&self, input: Vec<InDim>) -> Vec<OutDim>;
fn static_forward(input: Vec<InDim>, layer: &Self) -> Vec<OutDim> {
layer.forward(input)
}
}
struct FtoI {}
struct ItoF {}
struct FtoS {}
impl Layer<f32, i32> for FtoI {
fn forward(&self, input: Vec<f32>) -> Vec<i32> {
// In real case, converts the input to output.
vec![1, 2, 3]
}
}
impl Layer<i32, f32> for ItoF {
fn forward(&self, input: Vec<i32>) -> Vec<f32> {
// In real case, converts the input to output.
vec![1., 2., 3.]
}
}
impl Layer<f32, String> for FtoS {
fn forward(&self, input: Vec<f32>) -> Vec<String> {
// In real case, converts the input to output.
vec![String::from("Hello"), String::from("world")]
}
}
fn main() {
let vec_float = vec![1., 2., 3.];
# These elements share Layer trait with different type parameters
let layers = hlist![FtoI {}, ItoF {}, FtoS {}];
let r = layers.to_ref().foldl(
hlist![
// All of the element are same and seem redundant. Can this argument be simplified?
Layer::static_forward,
Layer::static_forward,
Layer::static_forward
],
vec_float,
);
/* This doesn't compile due to "type mismatch in function arguments "
let r = layers.to_ref().foldl(Layer::static_forward, vec_float);
*/
println!("result: {:?}", r);
}
答案 0 :(得分:0)
从@ 1tgr得到了有关使用宏的想法。下面是我的实现。这需要为每个可能调用的“ N”手动定义“ @cons”部分,并在宏参数中指定“ 3”。
仍然在寻找更好的解决方案。
macro_rules! hcons_repeat {
(@cons (0, $_e:expr))
=> { HNil };
(@cons (1, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (0, $e))}};
(@cons (2, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (1, $e))}};
(@cons (3, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (2, $e))}};
(@cons (4, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (3, $e))}};
(@cons (5, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (4, $e))}};
(@cons (6, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (5, $e))}};
(@cons (7, $e:expr))
=> { HCons{ head: $e, tail: hcons_repeat!(@cons (6, $e))}};
[$e:expr; $n:tt] => {
{
hcons_repeat!(@cons ($n, $e))
}
};
}
...
let r = layers
.to_ref()
.foldl(hcons_repeat![Layer::static_forward; 3], vec_float);