Search code examples
scalascala-option

Processing Scala Option[T]


I have a Scala Option[T]. If the value is Some(x) I want to process it with a a process that does not return a value (Unit), but if it is None, I want to print an error.

I can use the following code to do this, but I understand that the more idiomatic way is to treat the Option[T] as a sequence and use map, foreach, etc. How do I do this?

opt match {
  case Some(x) => // process x with no return value, e.g. write x to a file
  case None => // print error message
}

Solution

  • Scala's Option is, sadly, missing a method to do exactly this. I add one:

    class OptionWrapper[A](o: Option[A]) {
      def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default)
    }
    implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o)
    

    which has the slightly nicer (in my view) usage

    op.fold{ println("Empty!") }{ x => doStuffWith(x) }
    

    You can see from how it's defined that map/getOrElse can be used instead of pattern matching.

    Alternatively, Either already has a fold method. So you can

    op.toRight(()).fold{ _ => println("Empty!") }{ x => doStuffWith(x) }
    

    but this is a little clumsy given that you have to provide the left value (here (), i.e. Unit) and then define a function on that, rather than just stating what you want to happen on None.

    The pattern match isn't bad either, especially for longer blocks of code. For short ones, the overhead of the match starts getting in the way of the point. For example:

    op.fold{ printError }{ saveUserInput }
    

    has a lot less syntactic overhead than

    op match {
      case Some(x) => saveUserInput(x)
      case None => printError
    }
    

    and therefore, once you expect it, is a lot easier to comprehend.