Matching Regular Expressions and Patterns in Scala Part II

How to continue this question

Here is the code that compiles and works correctly using captures.

val myString = "ACATCGTAGCTGCTAGCTG" val nucCap = "([ACTG]+)".r myString match { case nucCap(myNuc) => println("dna:"+myNuc) case _ => println("not dna") } >scala scalaTest.scala dna:ACATCGTAGCTGCTAGCTG 

Here is a simpler code without capture which does not compile.

 val myString = "ACATCGTAGCTGCTAGCTG" val nuc = "[ACGT]+".r myString match { case nuc => println("dna") case _ => println("not dna") } >scala scalaTest.scala scalaTest.scala:7: error: unreachable code 

It seems that a match should return a boolean regardless of whether capture is used. What's going on here?

+7
source share
1 answer

In your block, match nuc is a template variable and does not apply to nuc in the scope. This makes the default case unattainable because a simple nuc pattern will match any.

An empty pair of brackets on nuc will make the syntax sugar work and call the unapplySeq method in Regex:

 myString match { case nuc() => println("dna") case _ => println("not dna") } 

One way to avoid this error is to rename nuc to nuc . Starting with an uppercase letter, it is a stable identifier, so that it refers to nuc in the scope, rather than being treated by the compiler as a template variable.

 val Nuc = "[ACGT]+".r myString match { case Nuc => println("dna") case _ => println("not dna") } 

The above text will print "not dna" because here we just compare nuc with myString and they are not equal. This is a mistake, but perhaps less confusing!

Adding brackets will have the desired effect in this case too:

 myString match { case Nuc() => println("dna") case _ => println("not dna") } // prints "dna" 

By the way, this is not a boolean that is returned, but Option[List[String]] :

 scala> nuc.unapplySeq(myString) res17: Option[List[String]] = Some(List()) scala> nucCap.unapplySeq(myString) res18: Option[List[String]] = Some(List(ACATCGTAGCTGCTAGCTG)) 
+8
source

All Articles