On Wed, Mar 12, 2014 at 10:05:27AM -0700, Kai wrote:
> @tailrec
> def sum(node: Tree, acc: Int): Int = node match {
> case Leaf(value) => acc + value
> case Node(value, left, right) => acc + value + Seq(sum(left, 0),
> sum(right, 0)).max
> }
> I can't for the life of me figure out how to build this in a way that it
> would be. Basically, when you have two recursive calls, how do you make it
> them a tail call?
>
> Is this even possible?
To do this without risking a stack overflow exception, you have to
simulate your own stack:
def sum(node: Tree): Int = {
def loop(node: Tree, stack: List[Tree], acc: Int): Int = node match {
case Leaf(n) =>
stack match {
case Nil => acc
case next :: rest => loop(next, rest, acc + n)
}
case Node(n, left, right) =>
loop(left, right :: stack, acc + n)
}
}
In general, when you have problems implementing a tail-recursive
method, you can use this transformation strategy.
-- Erik
P.S. I didn't try compiling this, but I'm pretty sure it works. The
pattern should be obvious.