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