scalafor-comprehensionunapply

Scala for comprehension unapplySeq


I have a

object radExtractor{
    def unapplySeq(row:HtmlTableRow):Option[List[String]]={
      val lista = (for{
        a<-row.getByXPath("td/span/a")
        ah= a.asInstanceOf[DomNode]
        if(ah.getFirstChild!=null)
      } yield a.asInstanceOf[DomNode].getFirstChild.toString).toList
      lista match{
        case Nil=>None
        case l @ List(duns,companyname,address,city,postal,_bs,orgnummer, _*) =>Some(l) 
        case _ =>println("WTF");None
      }
    }
  }

and I want to use it in a list comprehension like:

val toReturn = for{
      rad<-rader
      val radExtractor(duns,companyname,address,city,postal,_,orgnummer,_*)=rad
} yield Something(duns,companyname,address,city,postal,orgnummer)

But when a "rad" in "rader" fails because the extractor returns None I get a MatchError.

Isn't the extractor for comprehension supposed to handle/ignore the None cases or did I just miss something?

I could do

    val toReturn = rader.collect{case radExtractor(duns,companyname,address,city,postal,_,orgnummer,  _*)=>
          Something(companyname=companyname,address=address,city=city,postalcode=postal,orgnummer=orgnummer,duns=duns.toInt)
}

But that would not be as sexy ;) Thank you


Solution

  • Because you are performing the pattern match in an assignment to a val:

    val radExtractor(duns,companyname,address,city,postal,_,orgnummer,_*)=rad
    

    ... the match must succeed, or you will encounter an error. The above syntax is valid outside a for-comprehension and Scala does not provide any special behaviour for non-matching cases.

    To filter out non-matching values in a for-comprehension, use the pattern directly to the left of the <-:

    val toReturn = for {
      radExtractor(duns,companyname,address,city,postal,_,orgnummer,_*) <- rader
    } yield Something(duns,companyname,address,city,postal,orgnummer)