summaryrefslogtreecommitdiff
path: root/src/library/scalax/util/control/TailRec.scala
blob: db6cbfa2ed7eedfb66ca2b6c96c846996db13347 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package scala.util.control

abstract class TailRec[+A]

object TailRec {

  case class Call[A](rest: () => TailRec[A]) extends TailRec[A]
  case class Done[A](result: A) extends TailRec[A]

  def tailcall[A](rest: => TailRec[A]) = new Call(() => rest)
  def done    [A](result: A) = new Done(result)
  def trampoline[A](body: TailRec[A]): A = {
    def loop(body: TailRec[A]): A = body match {
      case Call(rest) => loop(rest())
      case Done(result) => result
    }
    loop(body)
  }
  def loop[A](body: TailRec[A]): A = body match {
    case Call(rest) => loop[A](rest())
    case Done(result) => result
  }
}