Given the following code snippelt:
import scala.util.Try
def foo(x:Int) : (Int, String) = {
(x+1, x.toString)
}
def main(args: Array[String]) : Unit = {
val r1: Try[(Int, String)] = for {
v <- Try { foo(3) }
} yield v
val r2: Try[(Int, String)] = for {
(i, s) <- Try { foo(3) } // compile warning refers to this line
} yield (i, s)
}
1. Why does a compile of the above code throw the following warning?
`withFilter' method does not yet exist on scala.util.Try[(Int, String)], using `filter' method instead
[warn] (i, s) <- Try { foo(3) }
[warn] ^
[warn] one warning found
2. Why is withFilter
used at all when extracting to a tuple?
Independent of the warning message, I'm heavily interested to know if withFilter
is used? (see question 2 )
It seems Try.withFilter
was only added in 2.11 (see Try
2.10.6 and Try
2.11.0)
withFilter
is used instead of filter
in a for comprehension because it is lazy, you can read a more comprehensive comparison in this question.
Your second for comprehension is similar to :
Try(foo(3)).withFilter {
case (i, s) => true
case _ => false
} map(identity)
Because in Scala 2.10.5 Try.withFilter
doesn't exists, it falls back to using filter
(which creates a new Try
).
Edit: Why you need the withFilter
is not that obvious in your case, because you aren't actually filtering with the (i, s)
pattern match.
If you wrote the for comprehension below, it is more clear that you (can) filter when you add a pattern match in the left hand side of a for comprehension.
for {
(i, "3") <- Try(foo(3))
} yield i
Which is analogous to :
Try(foo(3)) withFilter {
case (i, "3") => true
case _ => false
} map { case (i, "3") => i }
As you can see withFilter
is not only used when you add an if guard, but also when you pattern match.