是否可以以普通绑定的方式定义(递归)函数?

时间:2019-04-08 17:22:39

标签: rust

是否有任何绑定(而不是定义)可能递归功能的方法?例如:

type F = fn(i32) -> i32;

// equivalent to |x| (x+1)*2
fn f: F = composite(add_by(1), mult_by(2));

// equivalent to |x| if x > 100 then {x} else {g(x*2)}
// note the recursion
fn g: F = branch(greater_than(100), identity, composite(mult_by(2), g));

我要实现的递归一般不是封闭的(问here),没有黑客就不可能实现,而是简单的具有更好语法的普通函数(类型签名和定义)。

type F复杂并且应该抽象使用时,例如

,这可能会有所帮助。
type Parser<T> = fn(&str) -> Option<(T, &str)>

1 个答案:

答案 0 :(得分:1)

我不知道add_bymult_bycomposite可以返回除闭包以外的其他任何东西,因为返回的“东西”必须记住(例如“捕获”)参数...

话虽如此,如果您创建add_by和co,就可以使它工作。进入宏而不是函数:

macro_rules! add_by {
   ($y:expr) => { { fn f (x: i32) -> i32 { x + $y } f } }
}

macro_rules! less_than {
   ($y:expr) => { { fn f (x: i32) -> bool { x < $y } f } }
}

macro_rules! compose {
   ($f:expr, $g:expr) => { { fn c (x: i32) -> i32 { $f ($g (x)) } c } }
}

macro_rules! branch {
   ($rec:ident, $test:expr, $if_true:expr, $if_false:expr) => { 
      {
         fn $rec (x: i32) -> i32 {
            if $test (x) { $if_true (x) } else { $if_false (x) }
         }
         $rec
      }
   }
}

fn main() {
    let g = branch!(g, less_than!(10), add_by!(1), compose!(add_by!(1), g));
    println!("Test: {}", g(4));
}

playground

此处的要点是,您需要将递归函数的名称作为参数提供给branch宏(参数$rec),然后可以从子菜单访问它。表达式。