Why is that the following will not compile
for { s <- List.empty[String] regex <- List.empty[scala.util.matching.Regex] regex(ss) = s if ss == "foo" } yield s But removing the if
for { s <- List.empty[String] regex <- List.empty[scala.util.matching.Regex] regex(ss) = s } yield s or rearranging the order of the two lists in the for comprehension
for { regex <- List.empty[scala.util.matching.Regex] s <- List.empty[String] regex(ss) = s if ss == "foo" } yield s compiles?
Scalafiddle: http://scalafiddle.net/console/2519ff98d434cb522589f54a9c5fcf55
2 Answers
Answers 1
You can see the translated for-comprehension using this command:
scalac -Xprint:all <file>.scala In your first example the resulting code looks like this (I cleaned up the output a bit):
List.empty[String] .flatMap(((s) => List.empty[scala.util.matching.Regex] .map(regex => { private[this] val x$2 = s match { case (x$1@regex((ss@_))) => scala.Tuple2(x$1, ss) }; val x$1 = x$2._1; val ss = x$2._2; scala.Tuple2(regex, x$1) }).withFilter((x$3 => x$3 match { case scala.Tuple2((regex@_), regex((ss@_))) => ss.$eq$eq("foo") })).map(((x$4) => x$4 match { case scala.Tuple2((regex@_), regex((ss@_))) => s }))) ) The problem seems to be that the withFilter clause uses the expression regex(ss) directly in the case statement, but the value regex it is not defined there. I'm not sure if this can be considered a flaw in the language specification, or in the compiler. The error message is certainly not very helpful.
You can read up on the details in chapter 6.19 of the Scala language specification.
Answers 2
This might help you.
import scala.util.matching.Regex import scala.util.control.Exception._ for { s <- List.empty[String] regex <- List.empty[scala.util.matching.Regex] ss <- extract(regex, s) if ss == "foo" } yield s def extract(regex: Regex, s: String): Option[String] = allCatch.opt { val regex(ss) = s ss }
0 comments:
Post a Comment