Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将进程发送到scalaz流中的多个接收器_Scala_Scalaz_Scalaz Stream - Fatal编程技术网

如何将进程发送到scalaz流中的多个接收器

如何将进程发送到scalaz流中的多个接收器,scala,scalaz,scalaz-stream,Scala,Scalaz,Scalaz Stream,如果我有一个简单的过程,它发送类型为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(

如果我有一个简单的过程,它发送类型为
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)
  }
}
隐式类ToBoth[O](p:Process[Task,O]){
def toBoth(s1:Sink[Task,O],s2:Sink[Task,O]):进程[Task,Unit]={
(对于(o您还可以使用和
to
将多个
接收器
连接到
进程

val p = io.stdInLines.observe(out1).to(out2)
observe
to
类似,但会回显传入接收器的内容。因此
io.stdInLines.observe(out1)
仍然会发出来自stdin的字符串(这意味着它属于
进程[Task,String]
),但也会将它们发送到接收器
out1


正如Eric指出的,也可以将
zip
Sink
s放在一起。下面是一个更详细的示例,它根据日志级别将日志文件的各行发送到不同的Sink:

sealed trait Loglevel
case object Info extends Loglevel
case object Debug extends Loglevel
case object Warning extends Loglevel

case class Line(level: Loglevel, line: String)

val outInfo = io.stdOutLines.contramap((l: Line) => "I: " + l.line)
val outDebug = io.stdOutLines.contramap((l: Line) => "D: " + l.line)
val outWarning = io.stdOutLines.contramap((l: Line) => "W: " + l.line)

val zipped = outInfo.zip(outDebug).zip(outWarning).map {
  case ((fInfo, fDebug), fWarning) =>
    (l: Line) => l.level match {
      case Info    => fInfo(l)
      case Debug   => fDebug(l)
      case Warning => fWarning(l)
    }
}

val lines = List(
  Line(Info, "Hello"),
  Line(Warning, "Oops"),
  Line(Debug, "ui ui"),
  Line(Info, "World"))

Process.emitAll(lines).liftIO.to(zipped).run.run
运行此命令将输出:

I: Hello
W: Oops
D: ui ui
I: World

这也是我的要求之一,也是我解决问题的方法:。想法是将两个接收器压缩为一个:声音您可以将
接收器
实现为
频道
,以供参考:我提出了一个问题,关于如何使我的上一个示例更好:
I: Hello
W: Oops
D: ui ui
I: World