是否可以以正常绑定的方式定义(递归)函数? [重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

有没有任何方法可以绑定(而不是定义)可能的递归函数?例如:

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)>
rust
1个回答
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),此时你可以从子表达式访问它。

© www.soinside.com 2019 - 2024. All rights reserved.