Unlock the Power of Scala's Chaining Utils: A Guide to Tap and Pipe

Senior Software Engineer at Snowflake. Expert in scalable architecture, cloud tech, and security. Passionate problem-solver and mentor.
There is an amazing util in Scala that is available in scala.util.chaining._. It adds two implicit methods to any scala object that allow chain commands (pipe) and apply side effects (tap).
Tap example
import scala.util.chaining._
trait StatsCounter {
def incr(counterName: String): Unit
}
object Solution extends App {
val value = 123
val counter: StatsCounter = ... // implementation
stringValue(value)
def stringValue(v: Int): String = {
// tap adds pure side effect without changing input value
v.toString.tap {
result => counter.incr(result)
}
// this code does the same without chaining
// val result = v.toString
// counter.incr(result)
// result
}
}
Pipe example
def calculate(value: Int) = {
value
.pipe(_ + 100)
.pipe(Some(_))
}
calculate(100) // returns Some(200)
Pipe + Tap example
def calculate(value: Int) = {
value
.tap(println)
.pipe(_ + 100)
.tap(println)
.pipe(Some(_))
.tap(println)
}
calculate(100)
/*
returns Some(200)
prints:
100
200
Some(200)
*/
Scala's chaining utils provide a powerful and efficient way to streamline code by enabling the use of tap and pipe methods. By leveraging these methods, developers can optimize their functional code, enhance readability, and improve overall productivity.