我没有让一个简单的scalaz-stream示例运行,从TCP读取并写入std out。
val src = tcp.reads(1024)
val addr = new InetSocketAddress(12345)
val p = tcp.server(addr, concurrentRequests = 1) {
src ++ tcp.lift(io.stdOutLines)
}
p.run.run
它只是坐在那里,而不是打印任何东西。
我还尝试使用to
进行各种安排,始终使用tcp.lift
咒语获得Process[Connection, A]
,包括
tcp.server(addr, concurrentRequests = 1)(src) map (_ to tcp.lift(io.stdOutLines))
甚至无法编译。
我是否需要wye
源和打印流一起?我在tcp
上找到nio
替换wye
的示例似乎表明了这一点,但Process
上似乎不再存在p.map(_.run.run).run.run
,因此不幸的是,混淆不幸
编辑结果表明,除了Paul解释的类型问题之外,还需要手动运行内部流程",例如通过执行{{1} }。我不认为这是执行此操作的惯用方式,但确实有效。
答案 0 :(得分:5)
您需要将src
传递到接收器以实际写入任何内容。我认为应该这样做:
import scalaz.stream.{io,tcp,text}
import scalaz.stream.tcp.syntax._
val p = tcp.server(addr, concurrentRequests = 1) {
tcp.reads(1024).pipe(text.utf8Decode) through tcp.lift(io.stdOutLines)
}
p.run.run
表达式src ++ tcp.lift(io.stdOutLines)
应该是类型错误。 tcp.reads(1024)
的类型为Process[Connection,ByteVector]
,tcp.lift(io.stdOutLines)
的类型为Process[Connection, String => Task[Unit]]
。附加这两个过程是没有意义的,而且它检查的唯一原因是Process[+F[_],+O]
的协方差。当您使用不相关的输出类型附加两个进程时,Scala会“帮助”推断Any
。
scalaz-stream的未来版本可能会在++
和其他利用协方差的函数上添加约束,以确保计算得到的最小上限不会像Any
或{{ 1}}。这对于防止这样的错误大有帮助。在此期间,请确保您了解您正在使用的所有功能的类型,它们的作用以及如何将它们粘在一起。