大叔,把Seq[ZIO]改成ZIO[Seq]
Zio, transform Seq[ZIO] to 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)
}
}
Required: RIO[Translator, Seq[Translation]]
Found : ZIO[Translator, Nothing, Seq[zio.Task[Translation]]
我尝试了 flatMap
、flatten
、collectAll
和 merge
,但我无法与任何人取得预期的结果。
如何将 Seq[ZIO[_, _, B]]
转换为 ZIO[_, _, Seq[B]]
?
谢谢
编辑: 似乎 ZIO.foreach
是最好的选择,但是由于 for comprehension,我仍然将它包裹在另一个 ZIO 中。
如果我没看错,你可以使用 cats
:
中的 traverse
函数来完成
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], locales: Seq[Locale]): RIO[Translator, 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, Throwable, Seq[B]] =
seqZIO.toList.sequence.map(_.toSeq)
sequence
签名是:
def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] =
traverse(fga)(ga => ga)
在这里我们看到什么功能做我们需要的。
它需要 G
的 Applicative
实例(G
在您的情况下是 ZIO
),我们只需使用 import zio.interop.catz._
导入它
此外,为了使列表能够调用 sequence
,我们需要为 List
导入 Traverse
实例:
通过 import cats.instances.list._
不幸的是,我们不能用 Seq
做同样的技巧,因为我们需要 sequence
的 Traverse
实例,我们应该在和之前来回转换 Seq
到 List
在 sequence
.
之后
有用的链接:
因为 for 循环转换为 flatMap
除了最后一行是 map
,你想添加 foreach
调用 within ] for循环。
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
}
这可能是个愚蠢的问题,但从 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)
}
}
Required: RIO[Translator, Seq[Translation]]
Found : ZIO[Translator, Nothing, Seq[zio.Task[Translation]]
我尝试了 flatMap
、flatten
、collectAll
和 merge
,但我无法与任何人取得预期的结果。
如何将 Seq[ZIO[_, _, B]]
转换为 ZIO[_, _, Seq[B]]
?
谢谢
编辑: 似乎 ZIO.foreach
是最好的选择,但是由于 for comprehension,我仍然将它包裹在另一个 ZIO 中。
如果我没看错,你可以使用 cats
:
traverse
函数来完成
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], locales: Seq[Locale]): RIO[Translator, 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, Throwable, Seq[B]] =
seqZIO.toList.sequence.map(_.toSeq)
sequence
签名是:
def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] =
traverse(fga)(ga => ga)
在这里我们看到什么功能做我们需要的。
它需要 G
的 Applicative
实例(G
在您的情况下是 ZIO
),我们只需使用 import zio.interop.catz._
导入它
此外,为了使列表能够调用 sequence
,我们需要为 List
导入 Traverse
实例:
通过 import cats.instances.list._
不幸的是,我们不能用 Seq
做同样的技巧,因为我们需要 sequence
的 Traverse
实例,我们应该在和之前来回转换 Seq
到 List
在 sequence
.
有用的链接:
因为 for 循环转换为 flatMap
除了最后一行是 map
,你想添加 foreach
调用 within ] for循环。
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
}