以下代码将流构建为由flatMap
展平的流树。问题是在迭代结果流时它不是堆栈安全的。什么是堆栈安全等效的代码?
import scalaz.Id._
import scalaz.StreamT
object StreamOverflow extends App {
def streams(branchingFactor: Int, depth: Int): StreamT[Id, Int] = {
if(depth == 0) {
StreamT.empty
} else {
StreamT.fromIterable(1 to branchingFactor) flatMap { _ =>
streams(branchingFactor, depth-1) }
}
}
streams(10, 10) foreach { _ => } // stack overflow
}
我正在使用scalaz 7.2.0-RC1。
答案 0 :(得分:2)
您可以使用Trampoline
代替Id
:
import scalaz.Id.Id
import scalaz.{ StreamT, ~> }
import scalaz.Free.Trampoline
import scalaz.syntax.applicative._
object trampolineId extends (Id ~> Trampoline) {
def apply[A](i: A): Trampoline[A] = i.point[Trampoline]
}
def streams(branchingFactor: Int, depth: Int): StreamT[Trampoline, Int] =
if (depth == 0) StreamT.empty else {
StreamT.fromIterable(1 to branchingFactor).trans(trampolineId).flatMap { _ =>
streams(branchingFactor, depth - 1)
}
}
现在像streams(10, 10).foreach(_ => ().point[Trampoline]).run
这样的东西可能会运行很长一段时间,但它不应该溢出堆栈。