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

问题描述 投票:0回答:1

假设我有以下案例类:

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()  
} 

任何帮助将不胜感激。

scala scala-cats
1个回答
0
投票

您可以先对每条记录调用

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()
© www.soinside.com 2019 - 2024. All rights reserved.