Idiomatic solution to pipe if

Viewed 171

In our project using Scala 2.12 we have copied the ChainingOps from Scala 2.13. We use it a lot and we have added one more method: pipeIf - when the predicate is false, we pass the value unchanged.

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

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

I am now experimenting porting to Scala 2.13 and this pipeIf concerns me a bit. All other methods in this package (pipe and tap) are already included in the Scala 2.13 library. I would prefer removing our package completely, but this pipeIf stays there sticking out like a sore thumb.

What is the idiomatic way to deal with "piping conditionally"? It is not that bad, but one gripe is it prevents using underscore form. It is normal to use the verbose if / else form, or is there some other way?

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

Why not just place it in a universally available implicit class?

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
Related