与scalaz流并行处理多个文件

时间:2013-11-21 17:29:54

标签: scala scalaz7 scalaz-stream

我正在尝试使用scalaz-stream同时处理多个文件,将单个函数应用于文件中的每一行,跨所有文件。 具体来说,假设我有一个带字符串列表的函数

def f(lines: Seq[String]): Something = ???

还有几个文件,第一个:

foo1
foo2
foo3

第二个:

bar1
bar2
bar3

整个过程的结果应该是:

List(
  f(Seq("foo1", "bar1")), 
  f(Seq("foo2", "bar2")), 
  f(Seq("foo3", "bar3"))
)

(或者更可能直接写入其他文件)

事先不知道文件的数量,并且不同文件之间的行数可能不同,但我可以使用默认值填充(在运行时)较短文件的末尾,或者删除更长的文件。

基本上,我需要一种方法将Seq[Process[Task, String]](通过io.linesR之类的东西获得)合并为一个Process[Task, Seq[String]]

实现这一目标的最简单方法是什么?

或者,更一般地说,如何将nProcess[F, I]个实例合并到一个实例Process[F, Seq[I]]中?

我确信为此目的有一些标准的组合器,但我无法弄明白...

感谢。

1 个答案:

答案 0 :(得分:4)

此组合器尚不存在,但您可以添加它。我认为这将是:

def zipN[F[_], A](xs: Seq[Process[F,A]]): Process[F,Seq[A]] = 
  if (xs.isEmpty) Process.halt
  else xs.map(_ map (Vector(_))).reduceLeft(_.zipWith(_)(_ ++ _))

你还可以添加zipAllN,它带一个值来填充序列(使用zipAllalignN,这允许流“输出”输出当它们用尽时进行处理。(因此输出序列可能会变短。)

我建议你把它实现为'平衡'减少而不是左右减少,因为它会更有效率。

如果您最终真实地执行此操作,请提交拉取请求+测试!