Collect from Option
Use get method (see the implementation given below) which wraps the given value around option and then collects required value.
Wrap the value using option and then collect what ever you want to collect.
Option(x: Any).collect { case 1 => 1 }
or
x get { case 2 => 2 } // get implementation is given below
Scala REPL
scala> Option(1).collect { case 1 => 1 }
res0: Option[Int] = Some(1)
scala> Option(2).collect { case str: String => "bad" }
<console>:12: error: scrutinee is incompatible with pattern type;
found : String
required: Int
Option(2).collect { case str: String => "bad" }
^
scala> Option(2: Any).collect { case str: String => "bad" }
res2: Option[String] = None
scala> Option(2: Any).collect { case 2 => "bad" }
res3: Option[String] = Some(bad)
Nicer API using Implicit Class
implicit class InnerValue[A](value: A) {
def get[B](pf: PartialFunction[Any, B]): Option[B] = Option(value) collect pf
}
Scala REPL
scala> implicit class InnerValue[A](value: A) {
| def get[B](pf: PartialFunction[Any, B]): Option[B] = Option(value) collect pf
| }
defined class InnerValue
scala> 2.get { case 2 => 2}
res5: Option[Int] = Some(2)
scala> 2.get { case 3 => 2}
res6: Option[Int] = None
Now you can just invoke get method and pass the partial function. Now you may get a value wrapped in Some or will get None.
Notice that the above API (get method) is not type safe, you can do
2.get { case str: String => str }
Which returns None.
Now if you want typesafe make the following change
Type safety
implicit class InnerValue[A](value: A) {
def get[B](pf: PartialFunction[A, B]): Option[B] = Option(value) collect pf
}
Notice in the partial function the input parameter type is A instead of Any.
Now, when you do
2.get { case str: String => str }
You will get compilation error.
scala> 2.get { case str: String => str }
<console>:15: error: scrutinee is incompatible with pattern type;
found : String
required: Int
2.get { case str: String => str }
Get around the compilation error
You can get around the compilation error by doing following
scala> (2: Any) get { case str: String => str}
res16: Option[String] = None