views:

83

answers:

1

I'm still a Scala noob, and this confuses me:

import java.util.regex._

object NumberMatcher {
  def apply(x:String):Boolean = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    return matcher.find
  }

  def unapply(x:String):Option[String] = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    if(matcher.find) {
      return Some(matcher.group())
    }
    None
  }
}

object x {
  def main(args : Array[String]) : Unit = {
    val strings = List("geo12","neo493","leo")
    for(val string <- strings) {
      string match {
        case NumberMatcher(group) => println(group)
        case _ => println ("no")
      }
    }
  }
}

I wanted to add pattern matching for strings containing digits ( so I can learn more about pattern matching ), and in unapply I decided to return a Option[String]. However, in the println in the NumberMatcher case, group is seen as a String and not as an Option. Can you shed some light? The output produced when this is ran is:

12,493,no

+5  A: 

Take a look at this example.

The unapply method returns Some value if it succeeded in extracting one, otherwise None. So internally the

case NumberMatcher(group) => println(group)

invokes unapply and looks whether it returns some value. If it does, we already have to true result and therefore no Option type remains. The pattern matching extracts the returned value from the option.

Dario
So `unapply` can only return an `Option` type? It can't return a String directly?
Geo
right. unapply can't return a String directly. If it did, how would you indicate that the pattern didn't match.
Ken Bloom
Unapply methods can return a boolean in which case the match block's case clause uses an empty pattern parameter list.
Randall Schulz