Skip to content

Instantly share code, notes, and snippets.

@segfo
Last active August 14, 2021 23:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save segfo/53e3035567105e702a196c5fabca9a5d to your computer and use it in GitHub Desktop.
Save segfo/53e3035567105e702a196c5fabca9a5d to your computer and use it in GitHub Desktop.
Rustで末尾再帰のトランポリン化
enum RetVal {
Num(u128),
Recursive(Box<dyn Fn() -> RetVal>),
}
fn trampoline(r: RetVal) -> u128 {
let mut r = r;
loop {
match &r {
RetVal::Recursive(func) => {
r = func();
}
RetVal::Num(n) => {
return *n;
}
}
}
}
fn main() {
println!("{}", trampoline(sigma(100000, 1)));
trampoline(fibonacci(50, 1, 1));
}
fn sigma(n: u128, ans: u128) -> RetVal {
if n <= 1 {
return RetVal::Num(ans);
}
return RetVal::Recursive(Box::new(move || sigma(n - 1, ans + n)));
}
fn fibonacci(n: u64, acc: u128, acc2: u128) -> RetVal {
print!("{} ", acc);
if n == 1 {
return RetVal::Num(acc);
}
return RetVal::Recursive(Box::new(move || (fibonacci(n - 1, acc2, acc + acc2))));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment