Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a rule that unapply will always return an Option?

I tried to create an unapply method to use in pattern matching, and I tried to make it return something different than Option, however, Eclipse shows that as an error. Is it a rule that unapply must return an Option[T] ?

EDIT: here's the code I'm trying to use. I switched the code from the previous section so that unapply returns a Boolean

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):Boolean = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    return matcher.find
  }
}

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

Eclipse says wrong number of arguments for object NumberMatcher. Why is that?

like image 683
Geo Avatar asked Dec 14 '09 20:12

Geo


2 Answers

If you want to return something with unapply, return it inside Some. Returning Boolean just tests if the match can be made or not.

Here is how a pattern matching is translated:

str match { 
  case NumberMatcher(group) => println(group)
  case _ => println("no")
}

Assuming NumberMatcher returns Option[...], it will do:

val r1 = NumberMatcher.unapply(str)
if (r1 != None) {
  val group = r1.get
  println(group)
} else {
  println("no")
}

If NumberMatcher returns Boolean, then you can have it receive something. In that case, this is what happens:

str match { 
  case NumberMatcher() => println("yes")
  case _ => println("no")
}

becomes

val r1 = NumberMatcher.unapply(str)
if (r1) {
  println("yes")
} else {
  println("no")
}

Note that this is a very superficial explanation. Case matches can test for constants, have additional guard conditions, alternatives, use unapply recursively, use unapplySeq, etc. Here I'm only showing very basic usage to address a specific question. I strongly advise searching for a fuller explanation of pattern matching.

like image 129
Daniel C. Sobral Avatar answered Nov 15 '22 21:11

Daniel C. Sobral


Take a look at this example again. I quote

The return type of an unapply should be chosen as follows:
* If it is just a test, return a Boolean. For instance case even()
* If it returns a single sub-value of type T, return a Option[T]
* If you want to return several sub-values T1,...,Tn, group them in an optional tuple Option[(T1,...,Tn)].

like image 25
Dario Avatar answered Nov 15 '22 21:11

Dario