The inefficient (tree-recursive) fib(n)
function calculates the n-th Fibonacci number. In Haskell:
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
Using the following identity:
gfib(n) = (fib(n), fib(n+1))
we could synthesize a linear recursive version:
fib n = fst (gfib n)
where gfib 0 = (0, 1)
gfib n = (b, a + b)
where (a, b) = gfib (n - 1)
On the other hand, there's a well-known tail-recursive version:
fib n = go n 0 1
where go 0 a b = a
go n a b = go (n - 1) b (a + b)
Now the question:
Is there a way to synthesize the tail-recursive version from the linear recursive one using the Burstall & Darlington's folding/unfolding technique? My goal is to understand how can I transform the lineal recursive program so the returning tuple were converted to two accumulating parameters so the resulting program were tail-recursive.
Context: functional programming, program synthesis/derivation, program transformation, induction