scalapattern-matchingfor-comprehension

Is it possible to pattern match on type in a Scala for expression?


I'm trying to use a for expression to map over an Option, but I only want to match if the contents of the Option are of a specific type. What I thought would work is this:

for {
  vcs: Mercurial <- maybeVcs
} yield vcs

But that yields the following compile error:

<console>:76: error: type mismatch;
 found   : sbtrelease.Mercurial => sbtrelease.Mercurial
 required: sbtrelease.Vcs => ?
                vcs: Mercurial <- get (releaseVcs in Compile)
                               ^

Is it possible to pattern match on type in a for expression?


Solution

  • It's really straightforward if you use collect instead of for:

    trait A
    case class B(x: Int) extends A
    case class C(y: Int) extends A
    
    val someB: Option[A] = Some(B(2))
    val someC: Option[A] = Some(C(2))
    val noneA: Option[A] = None
    someB.collect { case n: B => n }   // Some(B(2))
    someC.collect { case n: B => n }   // None
    noneA.collect { case n: B => n }   // None