Suppose I've got partial function parf
val parf: PartialFunction[Int, String] = { case 0 => "!!!" }
Now I've got also case class A(x: Int)
and I need a function to transform PartialFunction[Int, String]
to PartialFunction[A, String]
:
def foo(pf: PartialFunction[Int, String]): PartialFunction[A, String] = ???
For example, foo(parf)
should return {case A(0) => "!!!" }
. How would you write function foo
?
To maintain the correct functionality, you need to check if the inner partial function is defined on a parameter you're going to pass:
val parf: PartialFunction[Int, String] = { case 0 => "!!!" }
case class A(x: Int)
def foo(pf: PartialFunction[Int, String]): PartialFunction[A, String] = {
case A(i) if pf.isDefinedAt(i) => pf(i)
}
If you plan to do it on a larger scale, you might want to convert a partial function to an extractor object, so it can be used in pattern matches directly with a better syntax:
trait Extractor[A, B] {
def unapply(a: A): Option[B]
}
object Extractor {
implicit def partialFunctionAsExtractor[A, B](pf: PartialFunction[A, B]): Extractor[A, B] =
new Extractor[A, B] {
def unapply(a: A) = if (pf.isDefinedAt(a)) Some(pf(a)) else None
}
}
def foo2(pf: Extractor[Int, String]): PartialFunction[A, String] = {
case A(pf(str)) => str
}
foo2(parf) // implicit conversion magic