使用scalaz流并行处理多个文件
我试图使用使用scalaz流并行处理多个文件,scala,scalaz7,scalaz-stream,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",
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
的方式获得)组合到一个进程[Task,Seq[String]]
实现这一目标的最简单方法是什么
或者,更一般地说,我如何将Process[F,I]
的n
实例组合成单个实例Process[F,Seq[I]]
我肯定有一些标准的组合器用于此目的,但我无法找出它
谢谢。此组合器尚不存在,但您可以添加它。我想会是这样的:
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(_)(_ ++ _))
您还可以添加zipAll
,这需要一个值来填充序列(并使用zipAll
,以及alignN
,这允许流在耗尽时“退出”输出进程。(因此,输出序列可能会变短。)
我建议您将其作为“平衡的”reduce而不是left或right reduce来实现,因为这样会更有效
如果你最终真的实现了这个功能,请提交一个pull请求+测试!这个组合器还不存在,但你可以添加它。我认为它将类似于:
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(_)(_ ++ _))
您还可以添加zipAll
,这需要一个值来填充序列(并使用zipAll
,以及alignN
,这允许流在耗尽时“退出”输出进程。(因此,输出序列可能会变短。)
我建议您将其作为“平衡的”reduce而不是left或right reduce来实现,因为这样会更有效
如果你最终真的实现了这个,请提交一个拉动请求+测试!谢谢你的回答,我会尝试用我的用例来实现它(如果顺利的话,还有一个后续的拉动请求)。虽然我不太确定你在这个上下文中所说的“平衡”是什么意思。所谓平衡,我指的是一个平衡的缩减树,所以
zip(zip(a1,a2,zip(a3,a4))
而不是zip(zip(a1,a2,a3),a4)
。感谢您的回答,我将尝试在我的用例中实现它(以及后续的拉取请求,如果顺利的话)。虽然我不太确定您在本文中所说的“平衡”是什么意思。所谓平衡,我指的是平衡的缩减树,所以zip(a1,a2),zip(a3,a4))
而不是zip(zip(zip(a1,a2,a3),a4)
。