查看来自Scala 函数式编程forever
的组合器:
trait AddlCombinators[F[_]] extends Monad[F] with Functor[F] {
def forever[A, B](a: F[A]): F[B] = {
lazy val t: F[B] = forever(a)
flatMap(a)(_ => t)
}
}
正如书中解释的那样,我遇到了 StackOverflow。
然后,我添加了一个count
变量,每次t
访问时递增它:
var count = 0
def forever[A, B](a: F[A]): F[B] = {
lazy val t = { println(count); count = count + 1; forever(a) }
}
然后,我创建了一个 ScalaTest 测试:
"running forever" should "throw a StackOverflow exception" in {
val listCombinator = new AddlCombinators[List] {
// omitted implementation of `Monad[List]` and `Functor[List]`
}
listCombinator.forever(List(1))
}
}
运行上述测试 3 次后,每次都在 ~1129/1130 上失败。
1129
[info] TestCombinators:
[info] running forever
[trace] Stack trace suppressed: run last test:testOnly for the full output.
[error] Could not run test test.TestCombinators: java.lang.StackOverflowError
为什么它在崩溃之前达到这个数字?另外,我如何推断每次执行forever
占用了多少堆栈内存?