gpt4 book ai didi

scala - 无标签final中的parSequence和parTraverse

转载 作者:行者123 更新时间:2023-12-03 21:13:33 26 4
gpt4 key购买 nike

使用 tagless final(不使用 IO,而是使用通用 F)我如何抽象出这样的东西:

def doSomething(s: String): IO[Unit] = ???

List("authMethods", "secretEngines", "plugins", "CAs", "common").parTraverse(doSomething)

我能得到的最接近的是使用 parTraverseN来自 Concurrent 对象,但我认为这将同时运行而不是并行运行(如 parallelism )。这也迫使我选择 nparTraverse才不是。

列表的大小只是一个例子,它可能更大。 doSomething是一个纯函数,它的多次执行可以毫无问题地并行运行。

理想情况下,鉴于 doSomething返回 IO[Unit]我想抽象过 parTraverse_F使用正确的类型类实例。

最佳答案

这是一个类似的完整工作示例:

import cats.Applicative
import cats.instances.list._
import cats.syntax.foldable._

trait Service[F[_]] {
val items = List("authMethods", "secretEngines", "plugins", "CAs", "common")

def doSomething(s: String): F[Unit] = ???

def result(implicit F: Applicative[F]): F[Unit] =
items.traverse_(doSomething)
}

如果您想使用 parTraverse_在这里,所需的最小更改如下所示:
import cats.{Applicative, Parallel}
import cats.instances.list._
import cats.syntax.parallel._

trait Service[F[_]] {
val items = List("authMethods", "secretEngines", "plugins", "CAs", "common")

def doSomething(s: String): F[Unit] = ???

def result(implicit F: Applicative[F], P: Parallel[F]): F[Unit] =
items.parTraverse_(doSomething)
}

或者,您可以使用 Parallel.parTraverse_(items)(doSomething)并跳过 syntax进口。这两种方法都需要一个 Foldable List 的实例(此处由 cats.instances.list._ 导入提供,在 Cats 2.2.0 中不再需要)和 Parallel F 的实例,您可以通过 P 获得约束。

(请注意, Applicative 上的 result 约束在第二个版本中不再需要,但这只是因为这是一个非常简单的例子——我假设你的真实代码依赖于类似 Sync 的东西,并且会需要那个和 Parallel 。)

不过,这个答案需要几个脚注。首先是 parTraverse_实际上可能不是一件好事。不会让您以 parTraverseN 的方式指定界限确实如此,并且可能会导致过多的内存使用等(但这将取决于例如列表的预期大小和 doSomething 正在执行的工作类型,并且可能超出了问题的范围)。

第二个脚注是 Parallel 意义上的“平行” type 类比 Cats“并发基础”文档中并行与并发区别中的“并行”更通用。 Parallel类型类模拟了一种非常通用的逻辑并行性,它也包含 error accumulation , 例如。所以当你写:

I assume this will run concurrently instead of in parallel (as in parallelism).



...您的假设是正确的,但不完全是因为 parTraverseN方法在 Concurrent而不是 Parallel ;请注意 Concurrent.parTraverseN仍然需要 Parallel实例。当你看到 parParallelcats.effect.Concurrent 的上下文中键入类,您应该考虑并发,而不是“并发基础”意义上的“并行”。

关于scala - 无标签final中的parSequence和parTraverse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62076571/

26 4 0