假设我有以下案例类:
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()
}
任何帮助将不胜感激。
您可以先对每条记录调用
processRecord
,然后再组合它们。还可以使用来自 cats 的 traverse
(适用于 List,因此将 Seq 转换为 List)
import cats.effect.IO
import cats.implicits._
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()