Scalaz';s traverse_uu与IO monad
我想用IO monad 但这段代码不会在大文件中运行。Scalaz';s traverse_uu与IO monad,scala,scalaz,Scala,Scalaz,我想用IO monad 但这段代码不会在大文件中运行。 我收到一个堆栈溢出错误。 我尝试了-dxs选项,但它抛出了相同的错误 val main = for { l <- getFileLines(file)(collect[String, List]).map(_.run) _ <- l.traverse_(putStrLn) } yield () val main=for{ l |>特效。putStrLn(e.shows)), 空=续(步骤(i)), eof=完成(i,e
我收到一个堆栈溢出错误。 我尝试了
-dxs
选项,但它抛出了相同的错误
val main = for {
l <- getFileLines(file)(collect[String, List]).map(_.run)
_ <- l.traverse_(putStrLn)
} yield ()
val main=for{
l |>特效。putStrLn(e.shows)),
空=续(步骤(i)),
eof=完成(i,eof[E]))
Cont(步骤(mzero[IO[单元]))
}
val main=用于{
我这是因为scalac没有为尾部调用优化循环
内部。循环
是尾部递归的,但我认为case
匿名函数语法会造成阻碍
编辑:实际上它甚至不是尾部递归(IO单子中的包装)在递归调用后导致至少一个调用。当我昨天进行测试时,我使用了类似的代码,但我删除了IO monad,然后可以使Iteratee尾部递归。下面的文本假设没有IO monad
我昨天在测试迭代器时碰巧发现了这一点。我认为将循环
的签名更改为这一点会有所帮助(因此目前您可能需要重新实现getFilesLines
和getReaderLines
:
@annotations.tailrec
def loop(it: IterV[String, A]): IO[IterV[String, A]] = it match {
// ...
}
我们可能应该向scalaz人报告这一点(并且可能会为scala开一张增强票)
这显示了发生了什么(代码与getReaderLines.loop
有点类似):
第一个问题是为什么/如何不使用大文件运行?您是否遇到堆栈溢出错误、内存不足错误或其他问题?我遇到了StackOverflower错误。我尝试了-DXss选项,但抛出了相同的错误。同意,我认为IO monad增加了一点挑战。请报告以便改进!
@annotations.tailrec
def loop(it: IterV[String, A]): IO[IterV[String, A]] = it match {
// ...
}
@annotation.tailrec
def f(i: Int): Int = i match {
case 0 => 0
case x => f(x - 1)
}
// f: (i: Int)Int
@annotation.tailrec
def g: Int => Int = {
case 0 => 0
case x => g(x - 1)
}
/* error: could not optimize @tailrec annotated method g:
it contains a recursive call not in tail position
def g: Int => Int = {
^
*/