scalaz StreamT 的 flatMap 的堆栈安全
Stack safety of scalaz StreamT's flatMap
以下代码将流构造为由 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。
您可以使用 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
这样的东西可能会 运行 很长时间,但它不应该溢出堆栈。
以下代码将流构造为由 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。
您可以使用 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
这样的东西可能会 运行 很长时间,但它不应该溢出堆栈。