Option
can be seen as a collection that has zero or exactly one element, and it provides a degree of interoperability with the collection types found in the package scala.collection
. In particular, it implements the interface IterableOnce
, which models the simplest form of collections: something that can be iterated over, at least once. However, Option
does not implement the more comprehensive interface of Iterable
. Indeed, we cannot provide a sensible implementation for the operation fromSpecific
, which is supposed to create an Option
from a collection of possibly more than one element. Starting from Scala 2.13, Option
was made an IterableOnce
but not an Iterable
.
Hence Option
can be used everywhere an IterableOnce
is expected, for example, when calling flatMap
on a collection (or inside a for-comprehension)
for {
a <- Set(1)
b <- Option(41)
} yield (a + b)
// : Set[Int] = Set(42)
for
a <- Set(1)
b <- Option(41)
yield (a + b)
// : Set[Int] = Set(42)
since the operation flatMap
on the type Set[Int]
takes a function returning an IterableOnce
:
def flatMap[B](f: Int => IterableOnce[B]): Set[B]
Although Option
does not extend Iterable
, there exists an implicit conversion between Option
and Iterable
implicit def option2Iterable[A](xo: Option[A]): Iterable[A]
so although Option[A]
is not a full collection it can be viewed as one. For example,
Some(42).drop(1)
// : Iterable[Int] = List()
expands to
Option.option2Iterable(Some(42)).drop(1)
// : Iterable[Int] = List()
because drop
is not defined on Option
. A downside of the above implicit conversion is that instead of getting back an Option[A]
we are left with an Iterable[A]
. For this reason, Option
’s documentation carries the following note:
Many of the methods in
Option
are duplicative with those in theIterable
hierarchy, but they are duplicated for a reason: the implicit conversion tends to leave one with anIterable
in situations where one could have retained anOption
.