1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#![no_std]
pub enum TCO<REC, RET> {
Rec(REC),
Ret(RET),
}
pub fn tco<A, B>(fun: fn(A) -> TCO<A, B>) -> impl Fn(A) -> B {
move |p: A| {
let mut c: TCO<A, B> = TCO::Rec(p);
loop {
match c {
TCO::Rec(i) => c = fun(i),
TCO::Ret(b) => return b,
}
}
}
}
#[test]
fn test() {
let f = tco(|(x, y): (i32, f64)| {
if (x == 0) {
TCO::Ret(y)
} else {
TCO::Rec((x - 1, y * (x as f64)))
}
});
assert_eq!(f((3, 1.0)), 6.0);
f((100000, 1.0));
}