scala - 如何用 scala cats 效果中的遍历来展平 for-compression ?

标签 scala scala-cats for-comprehension cats-effect

我有一些结构与此相同的代码,但我不确定清理它的最佳方法?那里有一些简单的 IO 和添加,因此该示例无需其他方法即可编译。

我真的不想让它如此嵌套,有没有办法让单个理解同时支持 IO 和 List?我知道这个问题的选项变体有 OptionT,但似乎没有等效的 ListT。

如有任何建议,我们将不胜感激

import cats.Traverse
import cats.effect.IO
import cats.implicits._

def exampleDoingSomeThings: IO[Unit] = for {
    ids <- IO.pure(List(1, 2, 3))
    _ <- ids.traverse[IO, Unit](id => for {
      users <- IO.pure(List(id + 4, id + 5, id + 6))
      data <- IO(id + 7)
      otherData <- IO(id + 8)
      _ <- users.traverse[IO, Unit](ud => for {
        innerData <- IO(id + ud)
        innerState <- IO(ud + 9)
        _ <- if (innerState > 15) for {
          _ <- IO(println(s"action1: $id $ud"))
          _ <- IO(println(s"action2: $id $ud"))
        } yield () else IO.pure()
      } yield ())
    } yield ())
  } yield ()

exampleDoingSomeThings.unsafeRunSync

https://scalafiddle.io/sf/S79H1ZI/0

最佳答案

正如其他人提到的,您可以将方法提取到子方法。但是,如果您发现这还不够,您可以使用类似 FS2 的库。或Monix让您的生活更轻松。它非常适合处理 IO + List 事物。

您可以将流可视化为逐项发出的项目列表。因此,您一次只需处理一个。

上面的例子可以翻译为(不包括未使用的变量):

莫尼克斯:

def monixThings: Observable[Unit] = for {
  id <- Observable.fromIterable(List(1, 2, 3))
  ud <- Observable.fromIterable(List(id + 4, id + 5, id + 6))
  innerState <- Observable.pure(ud + 9)
  _ <- Observable.fromTask {
    if (innerState > 15) {
      for {
        _ <- Task.delay(println(s"action1: $id $ud"))
        _ <- Task.delay(println(s"action2: $id $ud"))
      } yield ()
    } else {
      Task.unit
    }
  }
} yield ()

monixThings.completedL.runSyncUnsafe()

https://scalafiddle.io/sf/BDKbGCq/0

FS2:

import cats.effect.IO
import fs2.Stream

object FS2Example extends App {

  def fs2Things = for {
    id <- Stream.emits(List(1, 2, 3))
    ud <- Stream.emits(List(id + 4, id + 5, id + 6))
    innerState <- Stream.emit(ud + 9)
    _ <- Stream.eval {
      if (innerState > 15) {
        for {
          _ <- IO(println(s"action1: $id $ud"))
          _ <- IO(println(s"action2: $id $ud"))
        } yield ()
      } else {
        IO.unit
      }
    }
  } yield ()

  fs2Things.compile.drain.unsafeRunSync()
}

关于scala - 如何用 scala cats 效果中的遍历来展平 for-compression ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59050483/

相关文章:

scala - 为什么这个简单的 Scala for comprehension 不执行 future ?

scala - 为了理解尝试使用未处理的异常的 monad

scala - 我的测试中 jacoco4sbt 不是 "detecting"。知道为什么吗?

scala - 从 Scala 使用的 Redis 客户端库建议

scala - 认证路由中的 http4s json 处理

scala - 理解时类型不匹配 : getting "Product with Serializable"

scala - 在spark中解析json

scala - 只有某些键的映射

scala - 如何以正确的方式使用 Scala Cats 验证?

scala - 缺少 Cats Functor[Future] 实例