λ Tony's Blog λ
scala.Option Cheat Sheet
Posted on January 16, 2008Many people who are coming in to Scala first encounter the Option type, which may be thought of (among other things) as a type-safe null
. They also encounter pattern matching as both a new and (relatively) powerful concept, but also one that is easy to understand. This leads to quite a lot of use of pattern matching and often excessively so in what I have observed.
Particularly with a type as trivial as Option
, it is almost always possible to do away with pattern matching by using a higher-order function. Use of this function is typically preferred over pattern matching as tighter code. In fact, it is important to observe that it is possible to encapsulate all forms of pattern matching over Option
with one simple higher-order function:
def option[A, X](o: Option[A])(none: => X, some: => A => X): X = ...
Then, all functions can be written in terms of this one and needn’t pattern match at all. For example, consider Option.map
:
def map[A, B](o: Option[A], f: A => B) =
option(o, None, a => Some(f(a)))
In this post, I am going to give some common uses of pattern matching, which many developers might find themselves performing, followed by the use of a function that already exists on Option
that encapsulates that given form of pattern matching. If you find yourself using pattern matching in a form not listed below, but feel it could be abstracted, then chances are that such a function exists in the Scalaz extension to scala.Option.
I will use the identifier foo
below to denote any particular function, including many functions composed, for example, foo(x)
may represent the composition of two functions f and g: f(g(x))
. I also use the identifier option
to denote any value of the type scala.Option
.
I hope this helps :)
flatMap
match {
option case None => None
case Some(x) => foo(x)
}
This code is equivalent to:
flatMap(foo(_)) option.
flatten
match {
option case None => None
case Some(x) => x
}
This code is equivalent to:
flatten option.
map
match {
option case None => None
case Some(x) => Some(foo(x))
}
This code is equivalent to:
map(foo(_)) option.
foreach
match {
option case None => {}
case Some(x) => foo(x)
}
This code is equivalent to:
foreach(foo(_)) option.
isDefined
match {
option case None => false
case Some(_) => true
}
This code is equivalent to:
isDefined option.
isEmpty
match {
option case None => true
case Some(_) => false
}
This code is equivalent to:
isEmpty option.
forall
match {
option case None => true
case Some(x) => foo(x)
}
This code is equivalent to:
forall(foo(_)) option.
exists
match {
option case None => false
case Some(x) => foo(x)
}
This code is equivalent to:
exists(foo(_)) option.
orElse
match {
option case None => foo
case Some(x) => Some(x)
}
This code is equivalent to:
orElse(foo) option.
getOrElse
match {
option case None => foo
case Some(x) => x
}
This code is equivalent to:
getOrElse(foo) option.
toList
match {
option case None => Nil
case Some(x) => x :: Nil
}
This code is equivalent to:
toList option.
coflatMap
1
match {
option case None => None
case Some(_) => Some(foo(option))
}
This code is equivalent to:
coflatMap(foo(_)) option.
duplicate
2
match {
option case None => None
case Some(_) => Some(option)
}
This code is equivalent to:
duplicate option.