Scalaz';s traverse_uu与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

我想用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,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 = {
                           ^
*/