Scala: How to use fold on an Option (syntax)

If you want to get a value out of a Scala Option, there are a few ways to do it. I’ll show those approaches in this article, and then discuss the approach if using the fold method on an Option.

Back to top

Directly extracting the value out of the Option

To directly extract the value out of an Option, you can use a match expression:

val res = option match {
    case Some(i) => i
    case None => default
}

You can also use getOrElse:

val res = option.getOrElse(default)
Back to top

Applying a function while extracting the value from the Option

If you want to get the value out of an Option while also applying a function to the value, you can use a match expression:

val res = option match {
    case Some(i) => f(i)
    case None => default
}

You can also use map followed by getOrElse:

val res = option.map(f).getOrElse(default)

Finally, an approach I’ve seen discussed recently is that you can also call fold on the Option:

val res = option.fold(default)(f)

That code applies the function f to the value in a Some, or returns the default value if option is really a None.

Back to top

Discussion: Using fold on Option

As I discuss in my tutorial on using fold and reduce in Scala, this use of fold is somewhat consistent with using fold on sequential collections, where fold takes an initial seed value and a folding function. In the example above you can think of the default value as being the seed value:

val res = option.fold(default)(f)

In this example, if option is a None, the default value is returned, and the function f is ignored. Alternatively, if option is a Some, default is ignored, and the function f is applied to the option value. In this regard this doesn’t feel like the usual use of fold, but the syntax of supplying a value in the first parameter list and a function in the second parameter list is consistent with using fold on a sequential collection.

Back to top

How fold works on a sequential collection

As a quick example of what I mean about how fold works on a sequential collection, here are a few examples in the Scala REPL. This is how fold works on a list that has values in it, which is analogous to calling fold on a Some:

scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)

scala> val y = x.fold(10)(_ + _)
y: Int = 16

As shown, fold uses both the default value and the folding function, which isn’t consistent with how fold works on an Option (specifically on a Some).

Next, this is how fold works on an empty list, which is analogous to calling fold on a None:

scala> val x: List[Int] = List()
x: List[Int] = List()

scala> val y = x.fold(10)(_ + _)
y: Int = 10

In this case this feels similar to using fold on a None, because both approaches use the seed value, and since there’s nothing in the Option or List, the folding function isn’t really used.

Back to top

More information

For more information on using techniques like this, see my Using higher-order functions with Option tutorial. In that article I show this fold technique along with many other higher-order functions that are available on the Scala Option type.

Back to top