Finkelson
Finkelson

Reputation: 3013

Scala: PartialFunction weird behavior

It's weird but my code prints u. Any ideas why does it do such stuff?

object PF extends App {
  val f1: PartialFunction[Int, String] = {
    case x: Int if x % 2 == 0 => "2"
  }

  val f2: PartialFunction[Int, String] = {
    case x: Int if x % 3 == 0 => "3"
  }

  val f3: PartialFunction[Int, String] = {
    case x: Int if x % 5 == 0 => "5"
  }

  val result = f1.orElse(f2.orElse(f3.orElse("<undef>")))
  println(result.apply(1))    
}

Upvotes: 1

Views: 62

Answers (1)

gzm0
gzm0

Reputation: 14842

Your code interprets the string "" as PartialFunction:

val result: PartialFunction[Int, String] = "<undef>"
result.apply(1) // second character of "<undef>" --> u

This happens through an implicit conversion from String to WrappedString which is a subtype of Seq[Char]. Further, Seq[T] is a subtype of PartialFunction[Int, T] (given an index, get an element of the Seq if it exists).

The last line reaches this case, since 1 is not divisible by any of 2,3,5 (so it falls through f1, f2 and f3).

What you would want instead is applyOrElse:

val fun = f1 orElse f2 orElse f3
fun.applyOrElse(1, "<undef>") // --> "<undef>"

Alternatively, you can specify a fallback partial function:

val result = f1 orElse f2 orElse f3 orElse {
  case _ => "<undef>"
}

Upvotes: 3

Related Questions