Recursion takes a large problem and breaks it down until it reaches some base cases. One popular example, is the factorial function.
```scala
def fact(x: Int): Int =
if x == 0 then
1
else if x == 1 then
1
else
x * fact(x - 1)
```
Though we can similarly arrive at the answer by starting at the base case `1` and multiplying until we reach `x`. This is called co-recursion.
```
1 * 2 * ... * x
```
`Unfold` allows us to create sequences given some initial state and a function that takes some state and produces a value for the sequence. For the factorial function, we want to keep track of in our state the last factorial computed and the current index. `(lastFact, currInd)`.
Therefore, our initial state is `(1, 0)`.
```scala
val fact_seq = () => Iterator.unfold((1, 0))((x, y) => Some(
x, // currFact
(x * (y + 1), y + 1) // (nextFact, nextInd)
))
val fact = (x: Int) => fact_seq().take(x + 1).toList.last
Now why is this useful when maybe the recursive version can seem cleaner? Co-recursion and in turn unfolding can help remove redundancies. Let's look at the Fibbonaci sequence for an example. The recursive version would be as follows:
```scala
def fib(n : Int): Int =
if n == 0 then
0
else if n == 1 then
1
else
fib(n - 1) + fib(n - 2)
```
Now let's trace through an execution of `fib(4)`
```
fib(4)
fib(3) + fib(2)
(fib(2) + fib(1)) + fib(2)
((fib(1) + fib(0)) + fib(1)) + fib(2)
((1 + fib(0)) + fib(1)) + fib(2)
((1 + 0) + fib(1)) + fib(2)
(1 + fib(1)) + fib(2)
(1 + 1) + fib(2)
2 + fib(2)
2 + (fib(1) + fib(0))
2 + (1 + fib(0))
2 + (1 + 0)
2 + 1
3
```
Notice how there are many redundant calculations, for example `fib(2)` is evaluated twice separately in line 3 above.
Now lets look at how `unfold` helps. For our state, we need to keep track of the last two evaluations. Therefore, we can represent our state as `(currentAnswer, nextAnswer)`.
```scala
val fib_seq = () => Iterator.unfold((0, 1))((x, y) => Some(x, (y, x + y)))
In the past, [I've written](/blog/haskellrealsequences/) about analyzing sequences from real analysis within Haskell. Within it, I was looking at the following sequence: