scala - 合并 scalaz-stream 输入进程在 stdin 上似乎为 "wait"

标签 scala scalaz scalaz-stream

我有一个简单的程序:

import scalaz._
import stream._

object Play extends App {
  val in1 = io.linesR("C:/tmp/as.txt")
  val in2 = io.linesR("C:/tmp/bs.txt")

  val p = (in1 merge in2) to io.stdOutLines
  p.run.run
}

文件 as.txt包含五个 a s 和文件 bs.txt包含 3 b s。我看到这种输出:
a
b
b
a
a
b
a
a
a

但是,当我更改 in2 的声明时如下:
val in2 = io.stdInLines

然后我得到了我认为意外的行为。根据文档 1 ,程序应该根据哪个流更快地提供数据从每个流中非确定性地提取数据。这应该意味着我看到一堆 a s 立即打印到控制台,但这根本不是发生的事情。

确实,直到我按下 ENTER , 没发生什么事。很明显,如果我随机选择一个流来从中获取下一个元素,那么行为看起来很像我期望的那样,如果该流被阻塞,合并的进程也会阻塞(即使另一个流包含数据)。

到底是怎么回事?

1 - 好吧,好吧,文档很少,但Dan Spiewak 在his talk 中说的很清楚它会捕获第一个提供数据的人

最佳答案

问题出在stdInLines的实现上.它是阻塞的,它从不 Task.fork s 一个线程。

尝试更改 stdInLines 的实现对这个:

def stdInLines: Process[Task,String] =
    Process.repeatEval(Task.apply { 
    Option(scala.Console.readLine())
    .getOrElse(throw Cause.Terminated(Cause.End))
})

原版io.stdInLines正在运行 readLine()在同一个线程中,所以它总是在那里等待,直到你输入一些东西。

关于scala - 合并 scalaz-stream 输入进程在 stdin 上似乎为 "wait",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26999733/

相关文章:

scala - 使用 scalaz-stream 计算摘要

scala - 如何将两个 scalaz 流与谓词选择器结合起来?

scala - 在 scala-akka actor 中,我应该在处理消息时打开一个 future 吗?

scala - 如何在游戏 2.3.0 中使用 securesocial

scala - HList.foldRight 在类型类的实现中使用时如何查找隐式?

scala - 可以使用 scalaz Arrow 组合吗?

scala - 什么时候在 Scala 中使用 ST monad?

json - 用 1 个元素解析 Json 列表(Scala/liftweb)

scala - Play Framework : Slick does not know how to map the given types

scalaz-stream:如何以与其余部分不同的方式处理 "header"(第一 block )?