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