Question

There are two ways to define PF: 1) with literal case {} syntax and 2) as explicit class. I need the following function throw a MatchError, but in the second case that doesn't happen.

1) with case

val test: PartialFunction[Int, String] =  {
  case x if x > 100 => x.toString
}

2) as class

val test = new PartialFunction[Int, String] {
  def isDefinedAt(x: Int) = x > 100
  def apply(x: Int) = x.toString
}

Should i, in the seconds case, manually call isDefinedAt, shouldn't it be called implicitly by the compiler?

Was it helpful?

Solution

You will have to call isDefinedAt manually in your apply method:

val test = new PartialFunction[Int, String] {
  def isDefinedAt(x: Int) = x > 100
  def apply(x: Int) = if(isDefinedAt(x)) x.toString else throw new MatchError(x)
}

If you want to avoid this code, you can simply use the first way to define your partial function. It is syntactic sugar and will result in a valid definition of both isDefinedAt and apply. As described in the Scala language specification, your first definition will expand to the following:

val test = new scala.PartialFunction[Int, String] {
  def apply(x: Int): String = x match {
    case x if x > 100 => x.toString
  }
  def isDefinedAt(x: Int): Boolean = {
    case case x if x > 100 => true
    case _ => false
  }
}

OTHER TIPS

isDefinedAt is not a guard: it is not checked whenever you call the PartialFunction.

In your first case, the MatchErroroccurs because of the pattern matching failure. Actually, you can find out how the Partialfunction is built in the first case in the §8.5 of the Scala Specification.

In the second case, apply is defined for all x and then your definition of isDefinedAt is not valid.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top