管道 if

问题描述

在我们使用 Scala 2.12 的项目中,我们复制了 the ChainingOps from Scala 2.13。我们经常使用它,我们又添加一个方法pipeIf - 当谓词为 false 时,我们不改变传递值

def pipe[B](f: A => B): B = f(self)

def pipeIf(cond: Boolean)(f: A => A): A = if (cond) f(self) else self

我现在正在尝试移植到 Scala 2.13,这个 pipeIf我有点担心。此包中的所有其他方法pipetap)都已包含在 Scala 2.13 库中。我宁愿完全取下我们的包裹,但这个 pipeIf 留在那里,像拇指酸痛一样伸出来。

处理“有条件管道”的惯用方法是什么?它并没有那么糟糕,但一个抱怨是它阻止使用下划线形式。使用冗长的 if / else 形式是正常的,还是有其他方式?

val newState = state.pipeIf(dt != 0)(_.simulate(dt))
val newState = state.pipe(state => if (dt != 0) state.simulate(dt) else state )

解决方法

为什么不把它放在一个普遍可用的隐式类中?

implicit class Kestrel[A](private val repr: A) {
  def pipeIf(cond: Boolean)(f: A=>A): A =
    if (cond) f(repr) else repr
  def pipeIf(cond: A=>Boolean)(f: A=>A): A =
    if (cond(repr)) f(repr) else repr
}

5.pipeIf(_ < 8)(_ * 2)  //res0: Int = 10
5.pipeIf(false)(_ * 2)  //res1: Int = 5