Search code examples
scalacombinatorspartialfunction

Combine a PartialFunction with a regular function


So, suppose, I want to provide a "catch all" fall back for a PartialFunction:

 val foo: PartialFunction[Int, String] = { case 1 => "foo" }
 val withDefault = foo orElse { _.toString }

This does not compile: missing parameter type for expanded function ((x$1) => x$1.toString). This:

  val withDefault = foo orElse { case x: Int => x.toString }

Does not compile either (same error).

This:

val withDefault = foo orElse { (x: Int) => x.toString }

fails with type mismatch; found : Int => String; required: PartialFunction[?,?]

The only way I could find to make it work is to spell out the whole thing:

val withDefault = foo orElse PartialFunction[Int, String] { _.toString }

Is there any better syntax for this? I mean, one without having to tell it that I am passing a partial function from int to string to where it expects to receive a partial function from in to string. This is not ambiguous at all, why do I have to do this?


Solution

  • Maybe you need applyOrElse:

    val withDefault = foo.applyOrElse(_: Int, (_: Int).toString)
    

    Or maybe you would like something like this:

    implicit class PartialFunToFun[A,B](val f: PartialFunction[A,B]) extends AnyVal {
      def withDefault(bar: A => B) = f.applyOrElse[A,B](_: A, bar)
    }
    

    and use it: foo.withDefault(_.toString)(1)

    Also if you want to get just another PartialFunction you can use the next syntax:

    val withDefault = foo.orElse[Int, String]{case x => x.toString}