Composing PartialFunctions with orElse when there is a wildcard case

Mar*_*lic 3 scala function-composition

Is it possible to orElse compose two PartialFunctions when the first function has case _ => wildcard pattern that matches anything thus in effect being a total function.

For example, given

val pf1: PartialFunction[Int, String] = {
  case 1 => "foo"
  case 2 => "bar"
  case _ => "wildcard"
}

val pf2: PartialFunction[Int, String] = {
  case 3 => "baz"
  case _ => "wildcard"
}
Run Code Online (Sandbox Code Playgroud)

then, out-of-the-box

(pf1 orElse pf2)(3)
Run Code Online (Sandbox Code Playgroud)

outputs wildcard. However, assuming we cannot modify pf1, can we compose with pf2 using some compfn such that we get in effect

{
  case 1 => "foo"
  case 2 => "bar"
  case 3 => "baz"
  case _ => "wildcard"
}
Run Code Online (Sandbox Code Playgroud)

where (pf1 compfn pf2)(3) would output baz?

Tim*_*Tim 6

You can turn pf1 into a true partial function by doing a second match to convert the "wildcard" result to a failed match.

val pf3: PartialFunction[Int, String] = (i: Int) => pf1(i) match {
  case s if s != "wildcard" => s
}
Run Code Online (Sandbox Code Playgroud)

And then

(pf3 orElse pf2)(3)
Run Code Online (Sandbox Code Playgroud)

If you want the precise syntax you showed then you need to use an implicit class:

implicit class addCompfn(f1: PartialFunction[Int, String]) {
  def compfn(f2: PartialFunction[Int, String]) = (i: Int) => f1(i) match {
    case s if s != "wildcard" => s
    case s => f2(i)
  }
}
Run Code Online (Sandbox Code Playgroud)

And then

(pf1 compfn pf2)(3)
Run Code Online (Sandbox Code Playgroud)