λ 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
option match {
case None => None
case Some(x) => foo(x)
}This code is equivalent to:
option.flatMap(foo(_))flatten
option match {
case None => None
case Some(x) => x
}This code is equivalent to:
option.flattenmap
option match {
case None => None
case Some(x) => Some(foo(x))
}This code is equivalent to:
option.map(foo(_))foreach
option match {
case None => {}
case Some(x) => foo(x)
}This code is equivalent to:
option.foreach(foo(_))isDefined
option match {
case None => false
case Some(_) => true
}This code is equivalent to:
option.isDefinedisEmpty
option match {
case None => true
case Some(_) => false
}This code is equivalent to:
option.isEmptyforall
option match {
case None => true
case Some(x) => foo(x)
}This code is equivalent to:
option.forall(foo(_))exists
option match {
case None => false
case Some(x) => foo(x)
}This code is equivalent to:
option.exists(foo(_))orElse
option match {
case None => foo
case Some(x) => Some(x)
}This code is equivalent to:
option.orElse(foo)getOrElse
option match {
case None => foo
case Some(x) => x
}This code is equivalent to:
option.getOrElse(foo)toList
option match {
case None => Nil
case Some(x) => x :: Nil
}This code is equivalent to:
option.toListcoflatMap1
option match {
case None => None
case Some(_) => Some(foo(option))
}This code is equivalent to:
option.coflatMap(foo(_))duplicate2
option match {
case None => None
case Some(_) => Some(option)
}This code is equivalent to:
option.duplicate