diff options
author | George Leontiev <folone@gmail.com> | 2013-08-19 21:57:50 +0200 |
---|---|---|
committer | George Leontiev <folone@gmail.com> | 2013-08-24 09:57:35 +0200 |
commit | fdc543760d619e287f980d5cadb183993ff6004c (patch) | |
tree | 0e0624bef4521aa3645fe8f165b5876e73b034b3 /test | |
parent | 168d27020b4b2b3c78365137e99ca1e85c90b01a (diff) | |
download | scala-fdc543760d619e287f980d5cadb183993ff6004c.tar.gz scala-fdc543760d619e287f980d5cadb183993ff6004c.tar.bz2 scala-fdc543760d619e287f980d5cadb183993ff6004c.zip |
Alter TailRec to have map and flatMap
As described in the "Stackless Scala with Free Monads" paper
scala> import scala.util.control.TailCalls._
import scala.util.control.TailCalls._
scala> :paste
// Entering paste mode (ctrl-D to finish)
def isEven(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(true) else tailcall(isOdd(xs.tail))
def isOdd(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail))
// Exiting paste mode, now interpreting.
isEven: (xs: List[Int])util.control.TailCalls.TailRec[Boolean]
isOdd: (xs: List[Int])util.control.TailCalls.TailRec[Boolean]
scala> isEven((1 to 100000).toList).result
res0: Boolean = true
scala> def fib(n: Int): TailRec[Int] =
| if (n < 2) done(n) else for {
| x <- tailcall(fib(n - 1))
| y <- tailcall(fib(n - 2))
| } yield (x + y)
fib: (n: Int)util.control.TailCalls.TailRec[Int]
scala> fib(40).result
res1: Int = 102334155
Diffstat (limited to 'test')
-rw-r--r-- | test/files/run/tailcalls.scala | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/test/files/run/tailcalls.scala b/test/files/run/tailcalls.scala index 1d4124e138..e5d8891cc7 100644 --- a/test/files/run/tailcalls.scala +++ b/test/files/run/tailcalls.scala @@ -391,7 +391,20 @@ object Test { def isOdd(xs: List[Int]): TailRec[Boolean] = if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail)) + def fib(n: Int): TailRec[Int] = + if (n < 2) done(n) else for { + x <- tailcall(fib(n - 1)) + y <- tailcall(fib(n - 2)) + } yield (x + y) + + def rec(n: Int): TailRec[Int] = + if (n == 1) done(n) else for { + x <- tailcall(rec(n - 1)) + } yield x + assert(isEven((1 to 100000).toList).result) + //assert(fib(40).result == 102334155) // Commented out, as it takes a long time + assert(rec(100000).result == 1) } |