Search code examples
scalapartialfunction

How to check if function is partial in Scala?


I have a method that receives a function, but that function may be partial, in such case I don't want it to fail with MatchError.

def doSomething[X,Y](opt:Option[X])(f:X=>Y)={
  f match {
    case p:PartialFunction[X,Y]=> opt.flatMap(p.lift) //This doesn't seem to work
    case _ => opt.map(f)
  }
}

That way I can use the method like this

doSomething(x){
case t if predicate(t) =>  otherMethod(t)
}

so in case I don't have a predicate, I can use it like this doSomething(x)(otherMethod) instead of

doSoemthing(x){
case t=> otherMethod(t)
}

Note: Looking for a solution that doesn't require catching MatchError exceptions


Solution

  • The syntax for partial function has been changed since 2.9 per SLS 8.5, so that even you do { case x => y}, it DOES NOT mean it is a partial function. Its type will be exact as you define it as.

    In your case, you defined it as X=>Y (as in your function parameter), so it is just a X=>Y (it got compiled into a regular function, and non match cases will throw MatchError), and even you do isInstanceOf[PartialFunciton[_,_]], it won't match.

    To make your scenario work, you can just simply cast the passed function as PartialFunction, like:

    doSomething(Some(1))({case 2 => 0}: PartialFunction[Int,Int]) //This returns None without MatchError
    

    while

    doSomething(Some(1)){case 2 => 0} //This gives MatchError and it is not recognized as PartialFunction inside the body
    

    This is probably not as convenient as you thought it is, but it is the only way to make it work. (or you define 2 separate functions for either case, like collect and map in standard library)