scalaz StreamT的flatMap

时间:2015-11-29 22:56:52

标签: scala scalaz

以下代码将流构建为由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。

1 个答案:

答案 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这样的东西可能会运行很长一段时间,但它不应该溢出堆栈。