Reputation: 4109
phi n 0 = 1
phi n l = 1 + 1 / phi n (l - 1)
Obviously, the last evaluated action is not recursive call, thus given implementation indeed throws with a sufficiently large l
.
So what's the way (if any) to rewrite recursion such that 1) it remains recursive, 2) becomes tail-optimized? I assume phi n l result
would work, however can't redefine accordingly... are there reliable methods/techniques how to tackle down such a problems?
Upvotes: 3
Views: 138
Reputation: 120711
So you have this computation tree:
+ l ╱ ╲ 1 ÷ ╱ ╲ 1 + l-1 ╱ ╲ 1 ÷ ╱ ╲ 1 ... ╲ + 1 ╱ ╲ 1 ÷ ╱ ╲ 1 1 0
Since this has a linear shape, you can indeed make it tail-recursive. For this you need to start at the bottom and keep the already-calculated right result in an accumulator variable.
phi _ l = go 0 1 -- n isn't actually used
where go l' acc
| l' < l = go (l'+1) $! 1 + 1/acc
| otherwise = acc
Not tested, there might be an off-by-1 error here.
Upvotes: 6