Suma
Suma

Reputation: 34423

Chaining operations on values without naming intermediate values

Sometimes I perform a sequence of computations gradually transforming some value, like:

def complexComputation(input: String): String = {
  val first = input.reverse
  val second = first + first
  val third = second * 3
  third
}

Naming variables is sometimes cumbersome and I would like to avoid it. One pattern I am using for this is chaining the values using Option.map:

def complexComputation(input: String): String = {
  Option(input)
    .map(_.reverse)
    .map(s => s + s)
    .map(_ * 3)
    .get
}

Using Option / get however does not feel quite natural to me. Is there some other way this is commonly done?

Upvotes: 5

Views: 425

Answers (2)

Dominik Bucher
Dominik Bucher

Reputation: 1509

As you mentioned, it's doable to implement pipe on your own, e.g.:

implicit class Piper[A](a: A) {
  def pipe[B](f: A => B) = {
    f(a)
  }
}

val res = 2.pipe(i => i + 1).pipe(_ + 3)
println(res)  // 6

val resStr = "Hello".pipe(s => s + " you!")
println(resStr)  // Hello you!

Or take a look at https://github.com/scala/scala/blob/v2.13.0-M5/src/library/scala/util/ChainingOps.scala#L44.

Upvotes: 1

Krzysztof Atłasik
Krzysztof Atłasik

Reputation: 22625

Actually, it will be possible with Scala 2.13. It will introduce pipe:

import scala.util.chaining._

input //"str"
 .pipe(s => s.reverse) //"rts"
 .pipe(s => s + s) //"rtsrts"
 .pipe(s => s * 3) //"rtsrtsrtsrtsrtsrts"

Version 2.13.0-M1 is already released. If you don't want to use the milestone version, maybe consider using backport?

Upvotes: 7

Related Questions