【发布时间】:2014-11-19 10:59:52
【问题描述】:
如果我有一个简单的进程,它发出 String 类型的值,并且我希望将这些值发送到多个接收器(即每个接收器都收到 String),我该怎么做?
例如,运行这个程序:
object Play extends App {
def prepend(s: String): String => String = s ++ _
val out1 = io.stdOutLines.map(prepend("1-") andThen _)
val out2 = io.stdOutLines.map(prepend("2-") andThen _)
val p = io.stdInLines to (out1 merge out2)
p.run.run
}
输出如下:
a //input
1-a
b //input
2-b
c //input
2-c
d //input
1-d
我希望输出是这样的:
a //input
1-a
2-a
b //input
2-b
1-b
c //input
2-c
1-c
d //input
1-d
2-d
编辑
我可以这样实现:
implicit class ToBoth[O](p: Process[Task, O]) {
def toBoth(s1: Sink[Task, O], s2: Sink[Task, O]): Process[Task, Unit] = {
(for (o <- p; n <- Process.emit(o) ++ Process.emit(o)) yield n) to (s1 interleave s2)
}
}
也就是说,我复制输入并交错输出。这可以概括:
def toAll(sinks: Sink[Task, O] *): Process[Task, Unit] = {
(for (o <- p; n <- Process.emitAll(sinks.map(_ => o))) yield n) to sinks.reduceLeftOption(_ interleave _).getOrElse(Process.empty)
}
编辑 2
我刚刚意识到泛化toAll 不起作用。 toBoth 确实如此
有没有更好的(内置)方法?
【问题讨论】:
-
这也是我的要求之一,这就是我解决它的方法:github.com/etorreborre/specs2/blob/specs2-three/common/src/main/…。这个想法是将 2 个接收器压缩为一个:github.com/etorreborre/specs2/blob/specs2-three/common/src/main/…
-
听起来你可以将
sinks实现为channels
标签: scala scalaz scalaz-stream