Zio,将 Seq[ZIO] 转换为 ZIO[Seq]

问题描述

这可能是一个愚蠢的问题,但从 ZIO 开始,我无法将 Seq[ZIO] 转换为 ZIO[Seq]

def translate(keys: Seq[String],locales: Seq[Locale]):RIO[Translator,Seq[Translation]] = {
  for {
    service <- ZIO.environment[Translator]
  } yield {
    // service.translate produce a zio.Task[Translation]
    keys.map(k => service.translate(k,locales)
  }
}

必需:RIO[Translator,Seq[Translation]]

找到:ZIO[Translator,nothing,Seq[zio.Task[Translation]]

我尝试了 flatMapflattencollectAllmerge,但我无法与任何人取得预期的结果。

如何将 Seq[ZIO[_,_,B]] 转换为 ZIO[_,Seq[B]]

谢谢

编辑: ZIO.foreach 似乎是最好的选择,但是由于理解的原因,我仍然将它包裹在另一个 ZIO 中。

解决方法

因为除了最后一行是 flatMap 之外,for 循环转换为 map,所以您想在 for 循环中添加 foreach 调用 .

def translate(keys: Seq[String],locales: Seq[Locale]): RIO[Translator,Seq[Translation]] = { 
  for {
    translator <- ZIO.environment[Translator]
    translations <- ZIO.foreach(keys)(translator.translate(_,locales))
  } yield translations
}
,

如果我猜对了,您可以使用 traverse 中的 cats 函数:

import cats.instances.list._
import cats.syntax.traverse._
import zio.{RIO,Task,ZIO}
import zio.interop.catz._

import java.util.Locale

case class Translation()
trait Translator {
  def translate(k: String,locales: Seq[Locale]): Task[Translation]
}

def translate(keys: Seq[String],Seq[Translation]] = {
  val translator: Translator = ???
  for {
    service <- ZIO.effect(translator)
    result  <- keys.toList.traverse(k => service.translate(k,locales))
  } yield result
}

对于映射 List[ZIO[_,_,B]]ZIO[_,List[B]],您可以使用 sequence 函数,我建议为此使用 cats 库。

import zio.ZIO
import zio.interop.catz._
import cats.syntax.traverse._
import cats.instances.list._

def ziosSequence[B](seqZIO: Seq[ZIO[Any,Throwable,B]]): ZIO[Any,Seq[B]] = 
  seqZIO.toList.sequence.map(_.toSeq)

sequence 签名是:

def sequence[G[_]: Applicative,A](fga: F[G[A]]): G[F[A]] =
  traverse(fga)(ga => ga)

在这里我们看到什么函数做我们需要的。 它需要 ApplicativeG 实例(在您的情况下,GZIO),我们只需使用 import zio.interop.catz._ 导入它 此外,为了使列表能够调用 sequence,我们需要为 Traverse 导入 List 实例: 来自import cats.instances.list._ 不幸的是,我们不能用 Seq 做同样的技巧,因为我们需要 Traverse 的实例 sequence,我们应该在之前和之前来回转换 SeqList sequence 之后。

有用的链接: