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 of using the fold
method on an Option
.
Directly extracting the value out of the Option
A common way to extract the value out of an Option
is with a match
expression:
val res = option match {
case Some(i) => i
case None => default
}
You can also use getOrElse
:
val res = option.getOrElse(default)
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 again 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 if the Option
is a Some
; but if the Option
value is actually a None
, it returns the default
value.
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. A small but concrete example looks like this:
def f(i: Int) = i + 1 val a = Some(1) val b = a.fold(0)(f) // result: b = 2
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.
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.
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.