scala - 如何在功能上处理日志记录的副作用

标签 scala collections functional-programming

我想在记录没有相邻记录的情况下登录。有没有纯粹的功能性方法来做到这一点?一种将副作用与数据转换分开的方法?

这是我需要做的一个例子:

val records: Seq[Record] = Seq(record1, record2, ...)

val accountsMap: Map[Long, Account] = Map(record1.id -> account1, ...)

def withAccount(accountsMap: Map[Long, Account])(r: Record): (Record, Option[Account]) = {
  (r, accountsMap.get(r.id))
}

def handleNoAccounts(tuple: (Record, Option[Account]) = {
  val (r, a) = tuple
  if (a.isEmpty) logger.error(s"no account for ${record.id}")
  tuple
}

def toRichAccount(tuple: (Record, Option[Account]) = {
  val (r, a) = tuple
  a.map(acct => RichAccount(r, acct))
}

records
.map(withAccount(accountsMap))
.map(handleNoAccounts) // if no account is found, log
.flatMap(toRichAccount)

因此,我认为这种方法存在多个问题,使其不尽如人意。

元组返回类型很笨拙。我必须在后两个函数中解构元组。

日志记录函数必须处理日志记录,然后返回没有变化的元组。尽管没有发生任何转换,但将其传递给 .map 感觉很奇怪——也许有更好的方法来获得这种副作用。

是否有有效的方法来清理它?

最佳答案

我可能错了(我经常错),但我认为这可以满足所有要求。

records
  .flatMap(r => 
    accountsMap.get(r.id).fold{
      logger.error(s"no account for ${r.id}")
      Option.empty[RichAccount]
    }{a => Some(RichAccount(r,a))})

关于scala - 如何在功能上处理日志记录的副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63408002/

相关文章:

scala - 为什么嵌套的 FlatMaps 会在 Scala 中炸毁堆栈?

scala - 使用spark.sql的任何表的选择查询有时给出零记录,但是在HIVE CLI中给出相同结果的选择查询

java - 排除SBT项目中生成的源码包目录

scala - 在使用RDD进行理解时发出警告

java - 通过线程构造函数按引用分配的列表变量不起作用

java - HashSet的retainAll使用接口(interface)

JavaScript:以函数式方式重新组织 Canvas 渲染

scala - NoSuchMethodError : org. apache.spark.internal.Logging

java - 覆盖 Collection 中的 equals 和 hashCode

swift - 可选类型上的 flatMap 提示在闭包内展开