Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala for comprehensions/loops and typed patterns

Tags:

scala

According to section 6.19 of the Scala Language Specification this for loop:

for (e <-p) e'

is translated to:

p <- e.withFilter{case p => true; case _ => false}.foreach{case p => e′}

So, why this small program:

object ForAndPatterns extends App {
  class A()
  class B() extends A

  val list: List[A] = List(new A(), new B(), new B())

  for {b: B <- list}
    println(b)
}

gives this compilation error:

Error:(7, 13) type mismatch;
 found   : proves.ForAndPatterns.B => Unit
 required: proves.ForAndPatterns.A => ?
   for {b: B <- list}

when this expression:

list.withFilter{case a: B => true; case _ => false}.foreach{case b => println(b)}

gives no error.

like image 651
Josep M Beleta Avatar asked Apr 23 '17 09:04

Josep M Beleta


1 Answers

The translation you get from specification is actually

list.withFilter{case b: B => true; case _ => false}.foreach{case b: B => println(b)}

but it still compiles and works. It seems like Scala is losing the case and translating to

list.withFilter{case b: B => true; case _ => false}.foreach{b: B => println(b)}

which would give the same error.

This turns out to be a known and old bug: https://github.com/scala/bug/issues/900.

Workaround provided there:

object Typed { def unapply[A](a: A) = Some(a) }

for { Typed(b: B) <- list } println(b)
like image 75
Alexey Romanov Avatar answered Nov 15 '22 22:11

Alexey Romanov