scala 如何在不调用内部不安全方法的情况下将合并结果与折叠合并

e7arh2l6  于 2023-10-18  发布在  Scala
关注(0)|答案(1)|浏览(82)

假设我有以下案例类:

case class Record(a: String, b: String)
case class Result(c: Int, d: Int)

还有一个函数,它做了很多事情,然后返回一个IO[Result]

def processRecord[record: Record]: IO[Result] = {
  ...
  // Returns an IO[Result]
}

我需要一个名为save的函数,它接收Records的列表,然后需要将所有结果合并合并为一个结果

def combineStorageResults(result1: Result, result2: Result) = {
  Result(result1.c + result2.c, result1.d/2 + result2.d/2)
}

我已经创建了以下代码,通过使用foldLeft函数来实现这一点。然而,正如你所看到的,我需要在过程中间调用unsafeRunSync,只是为了在最后将结果打包到IO中。我想知道是否有任何方法可以做到这一点,但不必在函数中间调用unsafeRunSync

def save(records: Seq[Record]): Future[Result] = {
    IO(records.foldLeft(Result(0, 0))((previousResult, evt) => {
        val processedResult = processRecord(evt).unsafeRunSync()
        combineStorageResults(previousResult, processedResult)
      }
    )).unsafeToFuture()  
}

任何帮助将不胜感激。

hgb9j2n6

hgb9j2n61#

您可以先对每条记录调用processRecord,然后将它们合并组合起来。还可以使用cats中的traverse(适用于List,因此将Seq转换为List)

import cats.effect.IO
import cats.syntax.all._

val processed: IO[List[Result]] = records.toList.traverse(processRecord)

val combined: IO[Result] = processed.map { l =>
  l.foldLeft(Result(0, 0))((previousResult, currentResult) => {
    combineStorageResults(previousResult, currentResult)
  })
}

combined.unsafeToFuture()

相关问题