4

タグレスファイナルを使用して(IOを使用せずに、むしろ一般的なFを使用して)、次のようなものを抽象化するにはどうすればよいですか:

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

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

私が得ることができる最も近いparTraverseNのは Concurrent オブジェクトからの使用ですが、これは並行ではなく並行して実行されると思います ( parallelismのように)。また、そうでないn場所を選択するように強制します。parTraverse

リストのサイズは一例にすぎず、もっと大きくなる可能性があります。doSomethingは純粋な関数なので、複数回実行しても問題なく並列実行できます。

理想的には、それdoSomethingが返されることを考えると、正しい型クラス インスタンスを持つにIO[Unit]抽象化したいと思います。parTraverse_F

4

1 に答える 1

6

同様の完全な動作例を次に示します。

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 2.2.0cats.instances.list._では不要になります) と、制約を介して取得する のインスタンスが必要です。ParallelFP

Applicative(2 番目のバージョンではon の制約resultが不要になっていることに注意してください。ただし、これは単にこれが非常に単純な例であるためです。実際のコードはSync代わりに のようなものに依存しており、それと の両方が必要になると想定していますParallel。)

ただし、この回答にはいくつかの脚注が必要です。parTraverse_1つ目は、境界を指定する方法で境界を指定しないことは実際には良いことではないparTraverseN可能性があり、過度のメモリ使用などを引き起こす可能性があることです.作業の種類doSomethingは行っており、おそらく質問の範囲外です)。

2 番目の脚注は、Parallel型クラスの意味での「並列」は、Cats の「同時実行の基本」ドキュメントの並列と同時の区別における「並列」よりも一般的であるということです。型クラスは、たとえば、エラー累積Parallelも含む非常に一般的な種類の論理的並列処理をモデル化します。だからあなたが書くとき:

これは、並列ではなく同時に実行されると思います(parallelismのように)。

…あなたの仮定は正しいですが、parTraverseNメソッドが;Concurrentの代わりにon であるため、正確ではありません。まだインスタンスが必要であるParallelことに注意してください。または のコンテキストで型クラスを見るときは、「並行処理の基本」の意味での「並列処理」ではなく、並行処理について考える必要があります。Concurrent.parTraverseNParallelparParallelcats.effect.Concurrent

于 2020-05-29T09:22:47.730 に答える