Search code examples
scalafunctional-programming

'tee' operation on Scala's option type?


Is there some sort of 'tee' operation on Option in Scala's standard library available? The best I could find is foreach, however its return type is Unit, therefore it cannot be chained.

This is what I am looking for: given an Option instance, perform some operation with side effects on its value if the option is not empty (Some[A]), otherwise do nothing; return the option in any case.

I have a custom implementation using an implicit class, but I am wondering whether there is a more common way to do this without implicit conversion:

object OptionExtensions {
  implicit class TeeableOption[A](value: Option[A]) {
    def tee(action: A => Unit): Option[A] = {
      value foreach action
      value
    }
  }
}

Example code:

import OptionExtensions._

val option: Option[Int] = Some(42)
option.tee(println).foreach(println) // will print 42 twice

val another: Option[Int] = None
another.tee(println).foreach(println) // does nothing

Any suggestions?


Solution

  • In order to avoid implicit conversion, instead of using method chaining you can use function composition with k-combinator. k-combinator gives you an idiomatic way to communicate the fact that you are going to perform a side effect.

    Here is a short example:

    object KCombinator {
      def tap[A](a: A)(action: A => Any): A = {
        action(a)
        a
      }
    }
    
    import KCombinator._
    
    val func = ((_: Option[Int]).getOrElse(0))
      .andThen(tap(_)(println))
      .andThen(_ + 3)
      .andThen(tap(_)(println))
    

    If we call our func with an argument of Option(3) the result will be an Int with the value of 6 and this is how the console will look like:

    3

    6